Download presentation
Presentation is loading. Please wait.
1
CS2013 Lecture 7 John Hurley Cal State LA
2
Review: Data types I Application data is typed--classified into various categories--such as int, boolean, String A data type represents a set of possible values, such as {..., -2, -1, 0, 1, 2, ...}, or {true, false} By typing our variables, we allow the computer to find some of our errors Some operations only make sense when applied to certain kinds of data--multiplication, searching Typing simplifies internal representation A String requires more and different storage than a boolean Slide by David Matuszek, University of Pennsylvania
3
Data types II A data type is characterized by: a set of values
a data representation, which is common to all these values, and a set of operations, which can be applied uniformly to all these values Slide by David Matuszek, University of Pennsylvania
4
Primitive types A primitive data type like char, byte, short, int, long, double has a set of values a data representation a set of operations These are “set in stone”—there is nothing the programmer can do to change anything about them Slide by David Matuszek, University of Pennsylvania
5
Classes A class is a data type
The possible values of a class are objects The data representation is a reference to a block of storage The structure of this block is defined by the fields (both inherited and immediate) of the class The operations on the objects are its methods Slide by David Matuszek, University of Pennsylvania, edited
6
Insertion into a List There are many ways you could insert a new value into a List: • As the new first element • As the new last element • Before a given value • After a given value • Before the nth element • After the nth element • Before the nth from the end • After the nth from the end • In the correct location to keep the list in sorted order We need to supply the ones that are useful and efficient for applications in which we might use the List type Slide by David Matuszek, University of Pennsylvania, edited
7
Efficiency A list is just a sequence of values—it could be implemented by a linked list or by an array Inserting as a new first element is efficient for a linked list representation, inefficient for an array Accessing the nth element is efficient for an array representation, inefficient for a linked list Inserting in the nth position is efficient for neither We don’t want to make it easy for the user (programmer writing an application that uses our data type) to be inefficient The user should just have to learn to use the interface of our data type. S/he should not have to understand the implementation. Slide by David Matuszek, University of Pennsylvania, edited
8
Abstract Data Types An Abstract Data Type (ADT) is:
a set of values a public interface, which is a set of operations that can be applied to any data structure of this type To abstract is to leave out details, keeping only the essential structure What part of a Data Type does an ADT leave out? An ADT specifies what the operations do, not how they work. Slide by David Matuszek, University of Pennsylvania, edited
9
Data Structures Many kinds of data consist of multiple values, organized (structured) in some way A data structure consists of multiple values Hence, an array is a data structure, but an integer is not When we talk about data structures, we are talking about the implementation of a data type If I talk about the possible values of, say, complex numbers, and the operations I can perform with them, I am talking about them as an ADT If I talk about the way the parts (“real” and “imaginary”) of a complex number are stored in memory, I am talking about a data structure An ADT may be implemented in several different ways A complex number might be stored as two separate doubles, or as an array of two doubles, or in some other way Slide by David Matuszek, University of Pennsylvania, edited
10
Data representation in an ADT
An ADT must obviously have some kind of representation for its data The user need not know the representation The user should not be allowed to tamper with the representation Solution: Make all data private But what if it’s really more convenient for the user to have direct access to the data? setters and getters Slide by David Matuszek, University of Pennsylvania, edited
11
What’s the point? Setters and getters allow you to keep control of your implementation For example, you decide to define a Point in a plane by its x-y coordinates, providing two public variables Later on, as you gradually add methods to this class, you decide that it’s more efficient to represent a point by its angle and distance from the origin, θ and ρ Sorry, you can’t do that—you’ll break too much code that accesses x and y directly If you had used setters and getters, you could redefine them to compute x and y from θ and ρ Slide by David Matuszek, University of Pennsylvania, edited
12
Implementing an ADT To implement an ADT, you need to choose:
a data representation must be able to represent all necessary values of the ADT Data should be private an algorithm for each of the necessary operations must be consistent with the chosen representation all auxiliary (helper) operations that are not in the contract should be private Remember: Once other people (or other classes) are using your code: It’s easy to add functionality You can only remove functionality if no one is using it! Slide by David Matuszek, University of Pennsylvania, edited
13
Declaring ADTs In Java, ADTs are often specified using Java interfaces or abstract classes. The actual data structures that implement the ADTs, are, of course, defined using classes. Slide by David Matuszek, University of Pennsylvania, edited
14
Summary A Data Type describes values, representations, and operations
An Abstract Data Type describes values and operations, but not representations An ADT should protect its data and keep it valid All, or nearly all, data should be private Access to data should be via getters and setters An ADT should provide: A contract; definitions of what needs to be done A necessary and sufficient set of operations Slide by David Matuszek, University of Pennsylvania, edited
15
More Data Structures So far we have studied arrays and Lists in detail. As you know, this class is called "Programming With Data Structures," and obviously, data structures are the main topic of the course. Over the next few weeks, we will introduce a wide array (ha!) of new data structures. Most of these data structures can be used as collections of a wide range of parameterizing types
16
Stack A Stack is a data structure from which we access data in the reverse of the order in which it was added to the stack. In other words, a stack is a Last In First Out (LIFO) structure. Picture a stack of pancakes. If you are eating them one at a time, you must eat the last one that went on the stack first.
17
Applications of Stacks
Direct applications Page-visited history in a Web browser Undo sequence in a text editor Chain of method calls in the Java Virtual Machine Indirect applications Auxiliary data structure for algorithms Component of other data structures © 2014 Goodrich, Tamassia, Goldwasser Stacks 17
18
Method Stack in the JVM main() { int i = 5; foo(i ); }
The Java Virtual Machine (JVM) keeps track of the chain of active methods with a stack When a method is called, the JVM pushes on the stack a frame containing Local variables and return value Program counter, keeping track of the statement being executed When a method ends, its frame is popped from the stack and control is passed to the method on top of the stack Allows for recursion main() { int i = 5; foo(i ); } foo(int j) { int k; k = j+1; bar( k); } bar(int m) { … } bar PC = 1 m = 6 foo PC = 3 j = 5 k = 6 main PC = 2 i = 5 © 2014 Goodrich, Tamassia, Goldwasser Stacks 18
19
Stack Operations The main stack operations:
19 Stack Operations The main stack operations: push: put an object at the top of the stack pop: take the object from the top of the stack (remove and retrieve) peek or top: get the top element without removing it
20
Stack Interface in Java
Java interface corresponding to our Stack ADT Assumes null is returned from top() and pop() when stack is empty Different from the built-in Java class java.util.Stack public interface Stack<E> { int size(); boolean isEmpty(); E top(); void push(E); E pop(); } © 2014 Goodrich, Tamassia, Goldwasser Stacks 20
21
Example © 2014 Goodrich, Tamassia, Goldwasser Stacks 21
22
22 The Stack Class The Stack class represents a last-in- first-out stack of objects. The elements are accessed only from the top of the stack. You can retrieve, insert, or remove an element from the top of the stack.
23
Stack 23 Using the JDK Stack class: package demos;
import java.util.Stack; public class Demo { public static void main(String[] args) { Stack<String> myStack = new Stack<String>(); System.out.println(myStack.isEmpty()?"Stack is empty": "Stack is not empty"); System.out.println("Size of stack = " + myStack.size()); myStack.push("Mary"); myStack.push("Bob"); myStack.push("Jack"); System.out.println(myStack.peek()); System.out.println(myStack.pop()); myStack.push("Sue"); myStack.push("Bill"); do { } while (!myStack.isEmpty()); }
24
Stack A simple generic stack class, with the stack implemented using an ArrayList: package stackdemo; // import java.util.*; public class GenericStack<T> { private ArrayList<T> stack = new ArrayList<T>(); private int top = 0; public int size() { return top; } public void push(T item) { stack.add(top++, item); public T pop() { return stack.remove(--top); What is the complexity of each operation? How would we implement peek?
25
package stackdemo; public class GenericStackDriver { public static void main(String[] args) { GenericStack<String> stringStack = new GenericStack<String>(); stringStack.push("Moe"); stringStack.push("Curly"); stringStack.push("Larry"); System.out.println(stringStack.pop()); GenericStack<Integer> integerStack = new GenericStack<Integer>(); integerStack.push(1); integerStack.push(2); System.out.println(integerStack.pop()); }
26
Parentheses Matching Each “(”, “{”, or “[” must be paired with a matching “)”, “}”, or “[” correct: ( )(( )){([( )])} correct: ((( )(( )){([( )])})) incorrect: )(( )){([( )])} incorrect: ({[ ])} incorrect: ( © 2014 Goodrich, Tamassia, Goldwasser Stacks 26
27
Parenthesis Matching (Java)
public static boolean isMatched(String expression) { final String opening = "({["; // opening delimiters final String closing = ")}]"; // respective closing delimiters Stack<Character> buffer = new LinkedStack<>( ); for (char c : expression.toCharArray( )) { if (opening.indexOf(c) != −1) // this is a left delimiter buffer.push(c); else if (closing.indexOf(c) != −1) { // this is a right delimiter if (buffer.isEmpty( )) // nothing to match with return false; if (closing.indexOf(c) != opening.indexOf(buffer.pop( ))) return false; // mismatched delimiter } return buffer.isEmpty( ); // were all opening delimiters matched? © 2014 Goodrich, Tamassia, Goldwasser Stacks 27
28
28 Queues A queue is a first-in/first-out data structure. Elements are appended to the end of the queue and removed from the beginning. The name queue suggests a group of people waiting in line. Elements are added (offered) at the back of the queue In a standard queue, elements are removed (polled or dequeued) from the beginning of the queue. In a priority queue, elements are assigned priorities. When accessing elements, the element with the most urgency is removed first.
29
Applications of Queues
Direct applications Waiting lists, bureaucracy Access to shared resources (e.g., printer) Multiprogramming Indirect applications Auxiliary data structure for algorithms Component of other data structures © 2014 Goodrich, Tamassia, Goldwasser Queues 29
30
The Queue ADT Auxiliary queue operations: Boundary cases:
Queues 1/12/2019 The Queue ADT The Queue ADT stores arbitrary objects Insertions and deletions follow the first-in first-out scheme Insertions are at the rear of the queue and removals are at the front of the queue Main queue operations: enqueue(object): inserts an element at the end of the queue object dequeue(): removes and returns the element at the front of the queue Auxiliary queue operations: object first(): returns the element at the front without removing it integer size(): returns the number of elements stored boolean isEmpty(): indicates whether no elements are stored Boundary cases: Attempting the execution of dequeue or first on an empty queue returns null © 2014 Goodrich, Tamassia, Goldwasser Queues 30 30
31
Example Operation Output Q enqueue(5) – (5) enqueue(3) – (5, 3)
dequeue() 5 (3) enqueue(7) – (3, 7) dequeue() 3 (7) first() 7 (7) dequeue() 7 () dequeue() null () isEmpty() true () enqueue(9) – (9) enqueue(7) – (9, 7) size() 2 (9, 7) enqueue(3) – (9, 7, 3) enqueue(5) – (9, 7, 3, 5) dequeue() 9 (7, 3, 5) © 2014 Goodrich, Tamassia, Goldwasser Queues 31
32
wrapped-around configuration
Array-based Queue Use an array of size N in a circular fashion Two variables keep track of the front and size f index of the front element sz number of stored elements Recall that we remove elements from the front. When the queue has fewer than N elements, array location r = (f + sz) mod N is the first empty slot past the rear of the queue normal configuration Q 1 2 r f wrapped-around configuration Q 1 2 f r © 2014 Goodrich, Tamassia, Goldwasser Queues 32
33
Queue Operations We use the modulo operator (remainder of division)
Algorithm size() return sz Algorithm isEmpty() return (sz == 0) Q 1 2 r f Q 1 2 f r © 2014 Goodrich, Tamassia, Goldwasser Queues 33
34
Queue Operations (cont.)
Operation enqueue throws an exception if the array is full This exception is implementation- dependent Algorithm enqueue(o) if size() = N 1 then throw IllegalStateException else r (f + sz) mod N Q[r] o sz (sz + 1) Q 1 2 r f Q 1 2 f r © 2014 Goodrich, Tamassia, Goldwasser Queues 34
35
Queue Operations (cont.)
Note that operation dequeue returns null if the queue is empty Algorithm dequeue() if isEmpty() then return null else o Q[f] f (f + 1) mod N sz (sz - 1) return o Q 1 2 r f Q 1 2 f r © 2014 Goodrich, Tamassia, Goldwasser Queues 35
36
Queue Interface in Java
Java interface corresponding to our Queue ADT Assumes that first() and dequeue() return null if queue is empty public interface Queue<E> { int size(); boolean isEmpty(); E first(); void enqueue(E e); E dequeue(); } © 2014 Goodrich, Tamassia, Goldwasser Queues 36
37
Array-based Implementation
© 2014 Goodrich, Tamassia, Goldwasser Queues 37
38
Array-based Implementation (2)
© 2014 Goodrich, Tamassia, Goldwasser Queues 38
39
Application: Round Robin Schedulers
We can implement a round robin scheduler using a queue Q by repeatedly performing the following steps: e = Q.dequeue() Service element e Q.enqueue(e) Queue Dequeue Enqueue Shared Service © 2014 Goodrich, Tamassia, Goldwasser Queues 39
40
40 The Queue Interface
41
Queue Implemented With LinkedList
41 Queue Implemented With LinkedList LinkedList implements the Queue interface, so you can use the queue methods with a LL. Declare your reference variable as a Queue to prevent confusing results from using non-queue methods.
42
42 Queue Suppose eight children will take turns on two swings. At each round, the next child in the queue gets swing # (round % 2). public static void main(String[] args) throws InterruptedException { int[] swings = { 1, 2, 3 }; Queue<String> queue = new LinkedList<String>(); queue.offer("Brian"); queue.offer("Diana"); queue.offer("Al"); queue.offer("Mary"); queue.offer("Mike"); queue.offer("Florence"); queue.offer("Carl"); queue.offer("Dennis"); int round = 0; while (!queue.isEmpty()) { System.out.println(queue.remove() + " uses swing # " + swings[round % swings.length]); Thread.sleep(500); round++; }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.