Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Chapter 17: Stacks and Queues Learn about stacks Examine various stack operations Learn how to implement a stack as an array Learn how to implement a.

Similar presentations


Presentation on theme: "1 Chapter 17: Stacks and Queues Learn about stacks Examine various stack operations Learn how to implement a stack as an array Learn how to implement a."— Presentation transcript:

1 1 Chapter 17: Stacks and Queues Learn about stacks Examine various stack operations Learn how to implement a stack as an array Learn how to implement a stack as a linked list Discover stack applications Learn about queues Examine various queue operations Learn how to implement a queue as an array Discover queue applications

2 2 Stacks Lists of homogeneous elements –Addition and deletion of elements occur at one end, called the top of the stack –Middle items are inaccessible Stacks are also called Last Input First Output (LIFO) data structures Examples: –a box of paper, a stack of coins, dinner trays, parking lot. –Only the top sheet of paper, coin, tray, or car are accessible at any one time

3 Computer science applications implement method calls –run-time stack (an array in memory storing information about the currently executing program-->successive method calls). As each function returns, the LIFO ordering ensures that control returns to the method that made the most recent call. Stacks are also used to convert recursive algorithms into nonrecursive algorithms typing text on a keyboard and making corrections with the backspace key –(you always erase the last character typed-LIFO!) 3

4 4 Stacks Various types of stacks

5 5 Stacks Operations Operations performed on stacks –Push: adds an element to the stack –Pop: removes an element from the stack –Peek: looks at the top element of the stack

6 6 Stacks Stack operations

7 //Interface: StackADT public interface StackADT { public void initializeStack();//initializes stack to an empty state. public boolean isEmptyStack();//determines whether the stack is empty. public boolean isFullStack(); //determines whether the stack is full. public T peek(); //returns the top element of the stack. public void push(T newItem); //adds newItem to the stack. public void pop(); //removes the top element of the stack. } stacks7

8 ADT Stack Representations Array –one-dimensional array as the representation of a stack –Size limitations Linked list –memory is allocated dynamically using reference variables. Trade-off in efficiency in terms of speed, storage, and memory usage. other factors like flexibility, and ease to understand, code, and maintain 8

9 9 Implementation of Stacks as Arrays array of reference variables Each element of the stack in an array slot –item at the bottom of the stack is stored in the first array element –item second to the bottom is stored in the second array element, etc top of the stack is the index of the last element added to the stack, stackTop Disadvantage - fixed size

10 10 Implementation of Stacks as Arrays (continued) UML class diagram of the class StackClass

11 11 Implementation of Stacks as Arrays Example of a stack

12 12 Constructors Default constructor public StackClass() { maxStackSize = 100; stackTop = 0; //set stackTop to 0 list = (T[]) new Object[maxStackSize]; //create the array }//end default constructor

13 13 Constructors // Constructor with a parameter public StackClass(int stackSize) { if (stackSize <= 0) { System.err.println("The size must be positive."); System.err.println("Creating an array of the size 100."); maxStackSize = 100; } else maxStackSize = stackSize; stackTop = 0; list = (T[]) new Object[maxStackSize]; //create the array }

14 14 Initialize Stack Method initializeStack public void initializeStack() { for (int i = 0; i < stackTop; i++) list[i] = null; stackTop = 0; }//end initializeStack

15 15 Empty Stack Method isEmptyStack public boolean isEmptyStack() { return (stackTop == 0); }//end isEmptyStack

16 16 Full Stack Method isFullStack public boolean isFullStack() { return (stackTop == maxStackSize); }//end isFullStack

17 17 Push Method push public void push(T newItem) { if (isFullStack()) System.err.println("Cannot push in a full stack!"); else { list[stackTop] = newItem; //add newItem at the //top of the stack stackTop++; //increment stackTop } }//end push

18 18 Peek Method peek public T peek() { if (isEmptyStack()){ System.err.println("No top - the stack is empty!"); return (T) list[0]; } return (T) list[stackTop - 1]; }//end peek

19 19 Pop Method pop public void pop() { if (isEmptyStack()) System.err.println("Cannot pop from an empty stack!"); else { stackTop--; list[stackTop] = null; } }//end pop

20 //Client - test print using a temp stack public class ClientStackArray { public static void main(String[] args) { StackClass intStack = new StackClass (10); StackClass tempStack = new StackClass (10); Integer stackItem; intStack.push(37); intStack.push(10); intStack.push(20); intStack.push(27); System.out.println("After push (37, 10, 20, 27) the top is: " + intStack.peek()); System.out.println("The original stack in reverse order is: "); while (!intStack.isEmptyStack()) { stackItem = intStack.peek(); System.out.print(stackItem + " "); tempStack.push(stackItem); intStack.pop(); } stacks20

21 System.out.println("\nAfter print, the original stack is empty, temp stack isthe reverse copy of the original."); System.out.println("The original stack in direct order (temp stack in reverse order)is:"); while (!tempStack.isEmptyStack()) { stackItem = tempStack.peek(); System.out.print(stackItem + " "); intStack.push(stackItem); tempStack.pop(); } System.out.println("\nAfter print, the copy stack is empty, the original stack was rebuilt."); System.out.println("Can use the original stack in the remaining program."); } } OUTPUT: After push (37, 10, 20, 27) the top is: 27 The original stack in reverse order is: 27 20 10 37 After print, the original stack is empty, temp stack is the reverse copy of the original. The original stack in direct order (temp stack in reverse order)is: 37 10 20 27 After print, the copy stack is empty, the original stack was rebuilt. Can use the original stack in the remaining program. stacks21

22 22 Linked Implementation of Stacks Arrays have fixed sizes –Only a fixed number of elements can be pushed onto the stack Dynamically allocate memory using reference variables –Implement a stack dynamically Similar to the array representation, stackTop is used to locate the top element –stackTop is now a reference variable

23 23 Linked Implementation of Stacks Nonempty linked stack

24 24 public class LinkedStackClass implements StackADT { //Node Definition: inner class StackNode private class StackNode { public T info; public StackNode link; public StackNode() {//Default constructor info = null; link = null; } public StackNode(T value, StackNode ptr) {//Alternate constructor info = value; link = ptr; } public String toString() { return info.toString(); } }

25 25 //Instance variable for class LinkedStackClass private StackNode stackTop; //reference variable to top public LinkedStackClass() {//Default constructor stackTop = null; } public void initializeStack() { stackTop = null; }

26 26 Empty Stack and Full Stack Methods isEmptyStack and isFullStack public boolean isEmptyStack() { return (stackTop == null); }//end isEmptyStack public boolean isFullStack() { return false; }//end isFullStack

27 27 Push Method push public void push(T newValue) { StackNode newNode; //reference variable to create the new node newNode = new StackNode (newValue, stackTop); stackTop = newNode; }

28 28 Peek Method peek public T peek() { if (stackTop == null){ System.err.println("No top - the stack is empty!"); return stackTop.info; } else return stackTop.info; }

29 29 Pop Method pop public void pop() { if (stackTop == null) System.err.println("Cannot pop from an empty stack!"); else stackTop = stackTop.link; }

30 //Client - test print with a temp stack public class ClientStackLL { public static void main(String[] args) { LinkedStackClass intStack = new LinkedStackClass (); LinkedStackClass tempStack = new LinkedStackClass (); Integer stackItem; intStack.push(37); intStack.push(10); intStack.push(20); intStack.push(27); System.out.println("After push (37, 10, 20, 27) the top is: " + intStack.peek()); System.out.println("The original stack in reverse order is: "); while (!intStack.isEmptyStack()) { stackItem = intStack.peek(); System.out.print(stackItem + " "); tempStack.push(stackItem); intStack.pop(); } stacks30

31 System.out.println("\nAfter print, the original stack is empty, temp stack is the reverse copy of the original."); System.out.println("The original stack in direct order (temp stack in reverse order)is:"); while (!tempStack.isEmptyStack()) { stackItem = tempStack.peek(); System.out.print(stackItem + " "); intStack.push(stackItem); tempStack.pop(); } System.out.println("\nAfter print, the copy stack is empty, the original stack was rebuilt."); System.out.println("Can use the original stack in the remaining program."); } } OUTPUT: After push (37, 10, 20, 27) the top is: 27 The original stack in reverse order is: 27 20 10 37 After print, the original stack is empty, temp stack is the reverse copy of the original. The original stack in direct order (temp stack in reverse order)is: 37 10 20 27 After print, the copy stack is empty, the original stack was rebuilt. Can use the original stack in the remaining program. 31

32 32 Applications of Stacks: Postfix Expression Calculator Infix notation –The operator is written between the operands Prefix or Polish notation –Operators are written before the operands –Does not require parentheses Reverse Polish or postfix notation –Operators follow the operands –Has the advantage that the operators appear in the order required for computation

33 33 Applications of Stacks: Postfix Expression Calculator Infix expressions and their equivalent postfix expressions

34 34 Applications of Stacks: Postfix Expression Calculator Algorithm to evaluate postfix expressions –Scan the expression from left to right –When an operator is found, back up to get the required number of operands –Perform the operation –Continue processing the expression

35 6 3 + 9 3 / 4 5 7 2 + - * stacks35

36 36 Nonrecursive Algorithm to Print a Linked List Backward  Naïve approach  Get the last node of the list and print it  Traverse the link starting at the first node  Repeat this process for every node  Traverse the link starting at the first node until you reach the desired node  Very inefficient

37 37 Print a Linked List Backward current = first; //Line 1 while (current != null) //Line 2 { stack.push(current); //Line 3 current = current.link; //Line 4 }

38 while (!stack.isEmptyStack()) //Line 5 { current = stack.peek(); //Line 6 stack.pop(); //Line 7 System.out.print(current + “ “); //Line 8 } 20 15 10 5 stacks38

39 class Stack members public Stack(); public boolean empty(); public Object peek () throws EmptyStackException public Object pop () throws EmptyStackException public Object push(Object obj) public int search(Object obj) stacks39

40 40 Queues  Data structure in which the elements are added at one end, called the rear, and deleted from the other end, called the front  A queue is a First In First Out data structure  As in a stack, the middle elements of the queue are inaccessible

41 Real-life analogies of a queue –Waiting lines: the first person in line is the first person served (out of line) while new people will join the line at its back (rear). –Assembly lines: products enter the assembly line from one end and exit from the opposite end in the same order in which they entered. –A phone call to a 1-800-xxx-xxxx number: your call enters a queue and you keep waiting for the next available agent till you reach the first position in the queue. stacks41

42 Computer science applications of a queue A network printer and the printer queue: your request to print enters a queue to wait its turn (FIFO order) Printing a large paper: the computer sends lines faster than the printer can print them, so the lines are held in a queue (FIFO order) Buffered input: –Input characters via the keyboard, each character is stored in a buffer (a special area in memory that functions as a queue). –the operating system enqueues them until a carriage return character is received. Next, the OS will examine the characters end remove them from the queue in the same order in which they were typed. the operating systems makes extensive use of queues; each I/O device has a queue associated with it in order to be able to satisfy multiple requests. stacks42

43 43 Queue Operations  isEmptyQueue- Determine whether the queue is currently empty or not.  isFullQueue- Determine whether the queue is currently full or not.  front- If queue not empty, return a copy of the front item  back- If queue not empty, return a copy of the back item.  enqueue(T newItem) : Add newItem to the rear  dequeue- Removes the item at the front of the queue  makeEmpty : Set queue to an empty state.

44 44 QueueException Class  Adding an element to a full queue and removing an element from an empty queue would generate errors or exceptions  Queue overflow exception  Queue underflow exception  Classes that handle these exceptions  QueueException extends RunTimeException  QueueOverflowException extends QueueException  QueueUnderflowException extends QueueException

45 public class QueueException extends RuntimeException { public QueueException(String msg) { super(msg); } } public class QueueUnderflowException extends QueueException { public QueueUnderflowException() { super("Queue Underflow"); } public QueueUnderflowException(String msg){ super(msg); } } public class QueueOverflowException extends QueueException { public QueueOverflowException() { super("Queue Overflow"); } public QueueOverflowException(String msg){ super(msg); } } stacks45

46 ADT Queue Representations:  one-dimensional array as the representation of a queue  static array-based implementation. In particular, the solution uses a ring buffer implementation (a circular array).  As with previous solutions for other ADTs, the major shortcoming of the array implementation is that queues must be limited in size.  An alternative that eliminates this restriction is representing a queue as a linked list. stacks46

47 //Interface: QueueADT public interface QueueADT { public void initializeQueue(); //initialize the queue to an empty state. public boolean isEmptyQueue(); //determine whether the queue is empty. public boolean isFullQueue(); //determine whether the queue is full. public T front() throws QueueUnderflowException; //return the first element of the queue. public T back() throws QueueUnderflowException; //return the last element of the queue. public void enqueue(T newItem) throws QueueOverflowException; //Method to add newItem to the queue. public void dequeue() throws QueueUnderflowException; //Method to remove the first element of the queue. } stacks47

48 48 Implementation of Queues as Arrays  Instance variables  An array to store the queue elements  queueFront: keeps track of the first element  queueRear: keeps track of the last element  maxQueueSize : specifies the maximum size of the queues

49 enqueue and dequeue To enqueue an element x we increment rear and set the element with index rear to x. To dequeue an element we increment front. If we keep a counter for the number of elements in the queue, the enqueue operation will also increment the counter, while the dequeue operation will decrement the counter. stacks49

50 enQueue('A'); stacks50

51 51 enQueue('B'); enQueue('C'); Queue after two more enqueue operations

52 52 deQueue(); Queue after the dequeue operation

53 Problem with this implementation: stacks53 after a number of enqueue and dequeue operations the queue may appear to be full (since rear may have reached the last valid index in the array) when in reality it may hold just a few elements (because some of them may have been dequeued).

54 54 Implementation of Queues as Arrays  Problems with this implementation  Arrays have fixed sizes  After various insertion and deletion operations, queueRear will point to the last array position  Giving the impression that the queue is full  Solutions  Slide all of the queue elements toward the first array position  Use a circular array

55 55 Implementation of Queues as Arrays (continued) Circular queue

56 56 Implementation of Queues as Arrays (continued) Queue with two elements at positions 98 and 99

57 57 Implementation of Queues as Arrays (continued) Queue after one more enqueue operation

58 Circular representation treats the first and the last elements of the array as though they were adjacent. Each time an item is added to the queue (enqueued), the value of rear is incremented by 1 (the index of the next element in the ring) and the item is stored in that position. When queueRear is the same as maxQueueSize, the next operation to add an item resets queueRear to 0. The statement that causes queueRear to rotate around the ring is (queueRear + 1) % maxQueueSize; The index queueFront also advances in the ring; queueFront is given by the expression (queueFront + 1) % maxQueueSize; stacks58

59 59 Constructors  Default constructor //Default constructor public QueueClass() { maxQueueSize = 100; queueFront = 0; //initialize queueFront queueRear = maxQueueSize - 1; //initialize queueRear count = 0; list = (T[]) new Object[maxQueueSize]; //create the //array to implement the queue }

60 60 initializeQueue  Method initilializeQueue public void initializeQueue() { for (int i = queueFront; i < queueRear;i = (i + 1) % maxQueueSize) list[i] = null; queueFront = 0; queueRear = maxQueueSize - 1; count = 0; }

61 61 Empty Queue and Full Queue  Methods isEmptyQueue and isFullQueue public boolean isEmptyQueue() { return (count == 0); } public boolean isFullQueue() { return (count == maxQueueSize); }

62 62 Front  Method front public T front() throws QueueUnderflowException { if (isEmptyQueue()) throw new QueueUnderflowException(); return (T) list[queueFront]; }

63 63 Back  Method back public T back() throws QueueUnderflowException { if (isEmptyQueue()) throw new QueueUnderflowException(); return (T) list[queueRear]; }

64 64 enqueue  Method enqueue public void enqueue(T queueElement) throws QueueOverflowException { if (isFullQueue()) throw new QueueOverflowException(); queueRear = (queueRear + 1) % maxQueueSize; //use the //mod operator to advance queueRear //because the array is circular count++; list[queueRear] = queueElement; }

65 65 dequeue  Method dequeue public void dequeue() throws QueueUnderflowException { if (isEmptyQueue()) throw new QueueUnderflowException(); count--; list[queueFront] = null; queueFront = (queueFront + 1) % maxQueueSize; //use the //mod operator to advance queueFront //because the array is circular }

66 66 Linked Implementation of Queues Simplifies many of the special cases of the array implementation Because the memory to store a queue element is allocated dynamically, the queue is never full Class LinkedQueueClass implements a queue as a linked data structure –It uses nodes of type QueueNode

67 //Class: LinkedQueueClass implements //Interface: QueueADT //Linked list implementation public class LinkedQueueClass implements QueueADT { //Node Definition: inner class QueueNode protected class QueueNode { T info; QueueNode link; //Default constructor public QueueNode() { info = null; link = null; } //Alternate constructor public QueueNode(T elem, QueueNode ptr) { info = elem; link = ptr; } public String toString() { return info.toString(); } } //Instance variable for class LinkedQueueClass private QueueNode queueFront; //reference variable to the first queue element private QueueNode queueRear; //reference variable to the last queue element stacks67

68 //Default constructor public LinkedQueueClass() { queueFront = null; queueRear = null; } 68

69 69 Linked Implementation of Queues (continued) Method initializeQueue public void initializeQueue() { queueFront = null; queueRear = null; }

70 70 Methods isEmptyQueue and isFullQueue public boolean isEmptyQueue() { return (queueFront == null); } public boolean isFullQueue() { return false; }

71 71 enqueue public void enqueue(T newElement) { QueueNode newNode; newNode = new QueueNode (newElement, null); //create //newNode and assign newElement to newNode if (queueFront == null) //if initially the queue is empty { queueFront = newNode; queueRear = newNode; } else //add newNode at the end { queueRear.link = newNode; queueRear = queueRear.link; } }//end enqueue

72 72 front and back public T front() throws QueueUnderflowException { if (isEmptyQueue()) throw new QueueUnderflowException(); return queueFront.info; } public T back() throws QueueUnderflowException { if (isEmptyQueue()) throw new QueueUnderflowException(); return queueRear.info; }

73 73 dequeue Method dequeue public void dequeue() throws QueueUnderflowException { if (isEmptyQueue()) throw new QueueUnderflowException(); queueFront = queueFront.link; //advance queueFront if (queueFront == null) //if after deletion the queue queueRear = null; //is empty, set queueRear to null } //end dequeue


Download ppt "1 Chapter 17: Stacks and Queues Learn about stacks Examine various stack operations Learn how to implement a stack as an array Learn how to implement a."

Similar presentations


Ads by Google