CS 10: Problem solving via Object Oriented Programming Keeping - - PowerPoint PPT Presentation
CS 10: Problem solving via Object Oriented Programming Keeping - - PowerPoint PPT Presentation
CS 10: Problem solving via Object Oriented Programming Keeping order Agenda 1. Stacks 2. Queues 2 Stacks add and remove from top, Queues add to back, remove from front Items inserted in order: 1, 12, 5 Add at Remove back from front
2
Agenda
- 1. Stacks
- 2. Queues
3
Stacks add and remove from top, Queues add to back, remove from front
Stack (LIFO)
12 1 5 Add and remove from top
Queue (FIFO)
1 12 5 Remove from front Add at back
Items inserted in order: 1, 12, 5
4
Stacks are a Last In, First Out (LIFO) data structure
Stack overview
- Think of stack of dinner plates (or Pez dispenser)
- Add item to the top, others move down
- To remove, take top item (last one inserted)
- Commonly used in CS – function calls, paren
matching, reversing items in collection…
- Operations
- push – add item to top of stack
- pop – remove top item and return it
- peek – return top item, but don’t remove it
- isEmpty – true if stack empty, false otherwise
NOTE: There is no size method in a Stack
5
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack Initially empty
6
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack push(1)
1
Operations Push 1 Top
7
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack push(12)
12
Operations Push 1 Push 12 Top
1
8
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack push(5)
12
Operations Push 1 Push 12 Push 5 Top
1 5
9
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack pop() –> returns 5
12
Operations Push 1 Push 12 Push 5 Pop – returns 5 Top
1 5 5
10
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack push(7)
12
Operations Push 1 Push 12 Push 5 Pop – returns 5 Push 7 Top
1 7
11
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack pop() –> returns 7
12
Operations Push 1 Push 12 Push 5 Pop – returns 5 Push 7 Pop – returns 7 Top
1 7 7
12
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack pop() –> returns 12 Operations Push 1 Push 12 Push 5 Pop – returns 5 Push 7 Pop – returns 7 Pop – returns 12 Top
1 12 12
13
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack pop() –> returns 1 Operations Push 1 Push 12 Push 5 Pop – returns 5 Push 7 Pop – returns 7 Pop – returns 12 Pop – returns 1 Top
1 1
14
Stack adds to top only, removes from top
- nly; Last In First Out (LIFO)
Stack pop() –> throw exception Operations Push 1 Push 12 Push 5 Pop – returns 5 Push 7 Pop – returns 7 Pop – returns 12 Pop – returns 1 Pop – throw exception Top
15
SimpleStack.java: Interface defining Stack
- perations
As with other ADTs, we use generics because we don’t really care what kind of data the Stack will hold The Stack functionality will be the same irrespective of the data type
16
A Singly Linked List works well for a Stack, using top as head of list
head
Initially empty
17
A Singly Linked List works well for a Stack, using top as head of list
data next
head
1 push(1) Add at front of linked list Set new element next to head (null) Set head to new element (1)
18
A Singly Linked List works well for a Stack, using top as head of list
head
push(12) data next data next 12 1 Add at front of linked list Set new element next to head (1) Set head to new element (12)
19
A Singly Linked List works well for a Stack, using top as head of list
head
push(5) data next data next 5 data next 12 1 Add at front of linked list Set new element next to head (12) Set head to new element (5)
20
A Singly Linked List works well for a Stack, using top as head of list
head
peek() return 5 data next data next 5 data next 12 1 Add at front of linked list Peek returns data from first element or throw exception if empty
21
A Singly Linked List works well for a Stack, using top as head of list
head
pop() return 5 data next data next 5 data next 12 1 Add at front of linked list Peek returns data from first element or throw exception if empty Pop from front of list Get data from head (5)
22
A Singly Linked List works well for a Stack, using top as head of list
head
pop() return 5 data next data next 5 data next 12 1 Add at front of linked list Peek returns data from first element or throw exception if empty Pop from front of list Get data from head (5) Set head = head.next (12)
23
A Singly Linked List works well for a Stack, using top as head of list
head
pop() return 12 data next data next 12 1 Add at front of linked list Peek returns data from first element or throw exception if empty Pop from front of list Get data from head (12)
24
A Singly Linked List works well for a Stack, using top as head of list
head
pop() return 12 data next data next 12 1 Add at front of linked list Peek returns data from first element or throw exception if empty Pop from front of list Get data from head (12) Set head = head.next (1)
25
A Singly Linked List works well for a Stack, using top as head of list
head
push(7) data next data next 7 1 Add at front of linked list Set new element next to head (1) Set head to new element (7) Peek returns data from first element or throw exception if empty Pop from front of list
26
A Singly Linked List works well for a Stack, using top as head of list
head
data next data next 7 1 Add at front of linked list Peek returns data from first element or throw exception if empty Pop from front of list Always operating from head Never need to traverse list All operations O(1) If you had a tail pointer, could you implement a Stack by adding at the tail?
- Adding at tail is easy (you did so in SA-4)
- How would you handle pop?
- No easy way to move tail pointer back one element
- Could use a doubly linked list, but easy to implement
Stack with singly linked list by operating at head
27
A Singly Linked List works well for a Stack, using top as head of list
SLLStack.java Implements SimpleStack interface, so must implment its methods Private Element class as we’ve seen before Data is of generic type T top keeps track of top of stack (same as head did), initially null peek() returns data of first Element in list but does not remove it pop() gets data from first Element in list, then sets top to next push() adds new Element at top Sets new Element next to top’s prior value
- All operations
Θ(1)
- Unlike an array,
this does not run
- ut of space
28
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 top = -1
29
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt top = 0 push(1) 1
30
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt top = 1 push(12) 1 12
31
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt top = 2 push(5) 1 12 5
32
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt To peek() if top >=0 return stack[top], else throw exception top = 2 peek() return 5 1 12 5
33
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt To peek() if top >=0 return stack[top], else throw exception To pop(), do peek() and set top -= 1 top = 1 pop() return 5 1 12 5
34
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt To peek() if top >=0 return stack[top], else throw exception To pop(), do peek() and set top -= 1 top = 2 push(7) 1 12 7
35
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt To peek() if top >=0 return stack[top], else throw exception To pop(), do peek() and set top -= 1 top = 1 pop() return 7 1 12 7
36
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt To peek() if top >=0 return stack[top], else throw exception To pop(), do peek() and set top -= 1 top = 0 pop() return 12 1 12 7
37
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt To peek() if top >=0 return stack[top], else throw exception To pop(), do peek() and set top -= 1 top = -1 pop() return 1 1 12 7
38
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt To peek() if top >=0 return stack[top], else throw exception To pop(), do peek() and set top -= 1 top = -1 pop() throw exception 1 12 7
39
We can implement a Stack using an array
Stack array implementation
1 2 3 4 5 6 7 8 9 Create array and set top = -1 To push(T elmt), add 1 to top and stack[top] = elmt To peek() if top >=0 return stack[top], else throw exception To pop(), do peek() and set top -= 1 Implementation is O(1) for all operations, never need to move items Might run out of space using an array, but can grow in amortized O(1) time Can use ArrayList and not run out of space As shown, leaves data in memory – security implications! top = -1 pop() throw exception 1 12 7
40
An ArrayList implementation makes sure the Stack does not run out of space
ArrayListStack.java
ArrayList as stack ArrayList size keeps track of isEmpty() peek() returns value of last item but does not change stack Throws exception if stack empty pop() removes and returns last item Throws exception if stack empty push() adds element to stack at end List add method grows array if needed, O(1) Implements SimpleStack interface LIFO: add to end (top) and remove from end -> O(1)
41
Agenda
- 1. Stacks
- 2. Queues
42
Queues are a First In, First Out (FIFO) data structure
Queue overview
- Think of line at a store, join in back, leave from front
- Used in simulations, queuing print jobs, running jobs, could
have used it for PS-1 to visit neighbor pixels
- Operations
- enqueue – add item at rear of queue
- dequeue – remove and return first item in queue
- front – return first item, but don’t remove it
- isEmpty – true if queue empty, false otherwise
- Java uses different names (first ones throw exceptions; second
- nes return false if unable to complete)
- enqueue == add() and offer()
- dequeue == remove() and poll()
- front == element() and peek()
43
Queues add to back, remove from front; Frist In First Out (FIFO)
Initially empty Queue
44
Queues add to back, remove from front; Frist In First Out (FIFO)
Queue enqueue(1)
1 enqueue() adds to back
45
Queues add to back, remove from front; Frist In First Out (FIFO)
Queue enqueue(12)
1 12 enqueue() adds to back
46
Queues add to back, remove from front; Frist In First Out (FIFO)
Queue enqueue(5)
1 12 5 enqueue() adds to back
12
47
Queues add to back, remove from front; Frist In First Out (FIFO)
Queue dequeue() Return 1
1 5 dequeue() removes from front
12
48
Queues add to back, remove from front; Frist In First Out (FIFO)
Queue enqueue(7)
5 7 enqueue() adds to back
5
49
Queues add to back, remove from front; Frist In First Out (FIFO)
Queue dequeue() Return 12
7 12 dequeue() removes from front
7
50
Queues add to back, remove from front; Frist In First Out (FIFO)
Queue dequeue() Return 5
5 dequeue() removes from front
51
Queues add to back, remove from front; Frist In First Out (FIFO)
Queue dequeue() Return 7
7 dequeue() removes from front
52
SimpleQueue.java: Interface defining Queue operations
SimpleQueue.java
53
Queues can be implemented with Singly Linked List using head and tail pointers
Queue implementation
- Easy to get/remove from head
- Use tail to add to back of queue
- Set new element next to null
- Set tail.next to new element
- Move tail to new element (tail = tail.next)
- All operations O(1)
data next
head
“Alice” data next “Bob” data next “Charlie”
tail
54
Queues can be implemented with Singly Linked List using head and tail pointers
SLLQueue.java Implements SimpleQueue interface Keep a pointer to head (for dequeue) and a pointer to tail (for enqueue) Private Element class, same a before, except construct doesn’t take next parameter; why? Will always set next to null because will always add at end Check if first item enqueue() at end of queue using tail dequeue() from front of queue using head
55
Arrays are seemingly unpromising as a Queue data structure, but can work well
Array implementation
- Could enqueue at back, dequeue from front
- enqueue is fast, just add item to end O(1)
- dequeue must move all elements left one space O(n)
- Could enqueue at front and dequeue from back
- enqueue must move all elements right one space O(n)
- dequeue is fast, just take last item O(1)
- Could track front (f) and rear (r) indexes (circular array)
- enqueue at r, then increment r
- dequeue at f, then increment f
- If f or r > m-1, wrap around to empty spaces at front
- Full or empty when f==r (full if size !=0)
- enqueue and dequeue O(1)
Empty f=r=0 size = 0
56
Array implementing a Queue using index for front and rear
Array implementing Queue
1 2 3 4 5 6 7 8 9 f r
front (f) is index of first element rear (r) is index of next free space (initially 0)
57
Array implementing a Queue using index for front and rear
Array implementing Queue
a 1 2 3 4 5 6 7 8 9
enqueue(a) size = 0 Set a at position rear
f r
58
Array implementing a Queue using index for front and rear
Array implementing Queue
a 1 2 3 4 5 6 7 8 9
enqueue(a) size = 1 Set a at position rear Set rear +=1, size +=1
f r
59
Array implementing a Queue using index for front and rear
Array implementing Queue
a b c d e f g h 1 2 3 4 5 6 7 8 9 f r
enqueue(b) through enqueue(h) size = 8 front stays at 0, rear +=1 and size +=1
- n each enqueue()
60
Array implementing a Queue using index for front and rear
Array implementing Queue
a b c d e f g h 1 2 3 4 5 6 7 8 9 r
dequeue() size = 8 Return item at front -> a
f
61
Array implementing a Queue using index for front and rear
Array implementing Queue
a b c d e f g h 1 2 3 4 5 6 7 8 9 f r
dequeue() size = 7 Return item at front -> a front +=1, size -=1
62
Array implementing a Queue using index for front and rear
Array implementing Queue
a b c d e f g h 1 2 3 4 5 6 7 8 9 f r
dequeue() size = 6 Return item at front -> b front +=1, size -=1
63
Array implementing a Queue using index for front and rear
Array implementing Queue
a b c d e f g h i 1 2 3 4 5 6 7 8 9 f
enqueue(i) size = 7 Set i at position rear rear +=1, size +=1
r
64
Array implementing a Queue using index for front and rear
Array implementing Queue
a b c d e f g h i j 1 2 3 4 5 6 7 8 9 f
enqueue(j) size = 8 Set j at position rear rear +=1, wrap around to index 0 size +=1
r
65
Array implementing a Queue using index for front and rear
Array implementing Queue
k b c d e f g h i j 1 2 3 4 5 6 7 8 9 f
enqueue(k) size = 9 Set k at position rear rear +=1, size +=1
r
66
Array implementing a Queue using index for front and rear
Array implementing Queue
k l c d e f g h i j 1 2 3 4 5 6 7 8 9 f
enqueue(l) size = 10 Set l at position rear rear +=1, size +=1
r
67
Array implementing a Queue using index for front and rear
Array implementing Queue
k l c d e f g h i j 1 2 3 4 5 6 7 8 9 f
Array is full (f==r and size != 0), now what? Grow by creating new larger array Copy elements from old array into new array How if front != 0 due to dequeue operations?
r
size = 10
68
Array implementing a Queue using index for front and rear
Array implementing Queue
k l c d e f g h i j 1 2 3 4 5 6 7 8 9 f
Copy old array from front to size-1 into new array starting at index 0
r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 … …
69
Array implementing a Queue using index for front and rear
Array implementing Queue
k l c d e f g h i j 1 2 3 4 5 6 7 8 9 f
Copy old array from front to size-1 into new array starting at index 0
r c d e f g h i j 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 … …
70
Array implementing a Queue using index for front and rear
Array implementing Queue
k l c d e f g h i j 1 2 3 4 5 6 7 8 9 f
Copy old array from index 0 to front-1 into new array starting at last index
r c d e f g h i j k l 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 … …
71
Array implementing a Queue using index for front and rear
Array implementing Queue
f
Set front = 0 and rear = size Set array to new array
r c d e f g h i j k l 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 … …
size = 10
72
73
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Open Parens: [, {, (, < Close parens: ], }, ), > Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid
Define matching open and close parens Pseudo code ensures matching parens
74
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid
[
Stack Open Parens: [, {, (, < Close parens: ], }, ), > Current character
[
75
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack
[ {
Open Parens: [, {, (, < Close parens: ], }, ), > Current character
{
76
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack
[ {
Open Parens: [, {, (, < Close parens: ], }, ), > Current character
}
77
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack -> { matches current } Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack
[
Open Parens: [, {, (, < Close parens: ], }, ), > Current character
}
78
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack
[ {
Open Parens: [, {, (, < Close parens: ], }, ), > Current character
{
79
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack
[
Open Parens: [, {, (, < Close parens: ], }, ), > Current character
} {
80
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack -> { matches current } Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack
[
Open Parens: [, {, (, < Close parens: ], }, ), > Current character
}
81
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack
[
Open Parens: [, {, (, < Close parens: ], }, ), > Current character
]
82
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack -> [ matches current ] Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack Open Parens: [, {, (, < Close parens: ], }, ), > Current character
]
83
We can use the simple stack to easily match parens in a string
JSON String Students: [ {“id”: 123, “name” : “Alice”} {“id”: 987, “name” : “Bob”} ] Pseudo code Parse each letter If open paren, add to stack If close paren If stack empty then invalid (close without an open) Pop stack Invalid if popped element doesn’t match close paren If end of string and empty stack, valid, else not valid Stack Open Parens: [, {, (, < Close parens: ], }, ), > Current character
84
MatchParens2.java uses Java’s Stack to check matching parenthesis
Define open and matching close parens check() will see if a string s is properly formatted with open and close parens Create new Stack of Characters to hold open parens Loop
- ver
String s If find open paren character, push it
- nto Stack
- If find close paren character, make
sure Stack not empty, and pop()
- Check popped open Character
matches close paren character If handled all characters, see if Stack empty, fail if not empty,
- therwise pass