1 / 32

Chapter 16 Stacks and Queues

Chapter 16 Stacks and Queues. Saurav Karmakar Spring 2007. Objective. In this chapter we will learn: Stacks Queues Different implementations (arrays and linked list) of both Comparison of implementation . Stack. A stack is a data structure that works on the principle of

wakanda
Télécharger la présentation

Chapter 16 Stacks and Queues

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 16Stacks and Queues Saurav Karmakar Spring 2007

  2. Objective • In this chapter we will learn: • Stacks • Queues • Different implementations (arrays and linked list) of both • Comparison of implementation

  3. Stack • A stack is a data structure that works on the principle of Last In First Out (LIFO). • So last item put on the stack is the first item that can be taken off, like a physical stack of books/plates. • In stack new elements are added to and removed from the top of the structure.

  4. Two Implementations of Stack • As Vector Storing the items contiguously . • As List Storing items noncontiguously.

  5. Stack • Can be implemented with an array and an integer that indicates the top element of the stack (tos). • Empty stack : tos = -1. • Basic Operations : PUSH and POP.

  6. How stack works Empty stack push(a) push(b) pop(b) tos=1 tos=0 tos=0 tos= -1

  7. Stack – Vector Implementation A stack can be implemented with an vector and an integer that indicates the index of the top element. template <class Object> class Stack{ { public: Stack( ); bool isEmpty( ) const; const Object & top( ) const; void makeEmpty( ); void pop( ); void push( const Object & x ); Object topAndPop( ); private: vector<Object> theArray; int topOfStack; }; //construct the stack Template <class Object> Stack<Object>::Stack():the Array(1){ topOfStack = -1; } //test if the stack is logically empty Template <class Object> Stack<Object>::isEmpty() const{ return topOfStack == -1; }

  8. The push/pop function (vector-based) template <class Object> void Stack<Object>::push( const Object & x ) { if( topOfStack == theArray.size( ) - 1 ) theArray.resize( theArray.size( ) * 2 + 1 ); theArray[ ++topOfStack ] = x; } // If there is no vector doubling, push takes constant time, otherwise it // takes O(N) time. But it does not happen often. template <class Object> void Stack<Object>::pop( const Object & x ) { if( isEmpty()) throw UnderflowException(); topOfStack--; }

  9. Linked List Implementation • Advantage of the linked list : using only one pointer per item at a time. • Disadvantage of contiguous vector implementation : using excess space equal to the number of vacant array items .

  10. Linked List Implementation of Stack • The stack class can be implemented as a linked list in which the top of the stack is represented by the first item in the list. topOfStack

  11. Linked List Implementation of Stack • Each stack item stores • element value • pointer to next element

  12. Application of Stack • Recognizing palindromes • Checking balanced expressions • Evaluating algebraic expressions is easier. • Searching networks, traversing trees (keeping a track where we are).

  13. Infix to Postfix Conversion • Scan the Infix string from left to right. • Initialise an empty stack. • If the scannned character is an operand, add it to the Postfix string. • If the scanned character is an operator and if the stack is emptyPush the character to stack. • If the scanned character is an Operator and the stack is not empty, compare the precedence of the character with the element on top of the stack (topStack). If topStack has higher precedence over the scanned character Pop the stack else Push the scanned character to stack. Repeat this step as long as stack is not empty and topStack has precedence over the character. • Repeat this step till all the characters are scanned. • (After all characters are scanned, we have to add any character that the stack may have to the Postfix string.) If stack is not emptyadd topStack to Postfix string and Pop the stack. • Repeat this step as long as stack is not empty. • Return the Postfix string.

  14. Example : String a+b*c-d

  15. Postfix Expression Evaluation for each character C in a given string { if C is an operand push C onto stack; else // C is an operator { pop item from stack, and store in Opr2; pop item from stack, and store in Opr1; result = Opr1 C Opr2, using C as an operator; push result onto stack; } }

  16. QUEUE • A queue is an abstract data struture where various entities such as data, objects, persons, or events are stored and waiting to be processed. • The most well known operation of the queue is the First-In-First-Out (FIFO) queue process . • In a FIFO queue, the first element in the queue will be the first one out

  17. Queue • Can be implemented using • Vector/Array • Link List • Two main Operations : • Enqueue • Dequeue

  18. Queue: Vector/Array Implementation • Store items in an vector/array with front item at index zero and back item at index Back. • Enqueue is easy: increment Back. • Dequeue is inefficient: all elements have to be shifted. (If use only one index) • Result: Dequeue will be O (N).

  19. Queue Step 1. makeEmpty() Back Step 4. dequeue() Back Step 2. enqueue() Back Step 3. enqueue() After dequeue() : Back Back

  20. a b c d Front Back a b c d Front Back Better Idea • Keep a Front index. • To Dequeue, increment Front. Therefore, Dequeue takes constant time now.

  21. Queue Step 1. makeEmpty() Step 4. dequeue() Back Back Front Step 2. enqueue() Back Front After dequeue() : Front Step 3. enqueue() Back Back Front Front

  22. Circular Implementation • Previous implementation is O( 1 ) per operation. • However, after vector.size() times enqueues, we are full, even if queue is logically nearly empty for dequeue opeartions on the elements. • Solution: use wraparound to reuse the cells at the start of the vector. To increment, add one, but if that goes past end, reset to zero.

  23. Problem with the approach : Back Front Solution : Recycle / Wrap Around Back Front

  24. Circular Example Both Front and Back wraparound as needed. b c d e f Front Back g b c d e f Back Front

  25. QUEUE--Vector Implementation • Mostly straightforward; maintain • Front • Back • CurrentSize: Current number of items in queue • Only tricky part is vector doubling because the queue items are not necessarily stored in an array starting at location 0, and the contiguity of wraparound must be maintained.

  26. Template <class Object> Class Queue{ public: Queue(); bool isEmpty() const; const Object & getFront() const; void makeEmpty(); Object dequeue(); void enqueue (const Ojbect & x); private: vector<Object> theArray; int currentSize; int front; int back; void increment (int & x) const; void doubleQueue(); } template <class Object> void Queue<Object>::enqueue(const Object & x){ if(currentSize == theArray.size()) doubleQueue(); increment( back); theArray[back] = x; currentSize++; } template <class Object> void Queue<Object>::doubleQueue() { theArray.resize(theArray.size() * 2 + 1); if(front != 0){ for(int i=0; i<front; i++){ theArray[i+currentSize] = theArray[i]; back += currentSize; } } Queue – Vector Implementation

  27. Queue – Vector Implementation cont. template <class Object> Object Queue<Object>::dequeue() { if( isEmpty()) throw UnderflowException(); currentSize--; Object frontItem = theArray[front]; increment(front); return frontItem; } template <class Object> const Object & Queue<Object>::getFront() const { if (isEmpty()) throw UnderflowException(); return theArray[front]; } template <class Object> void Queue<Object>::makeEmpty(){ currentSize = 0; front = 0; back = theArray.size() –1; }

  28. Linked List Implementation • Advantage of the linked list is excess memory is only one pointer per item. • In contrast, a contiguous vector implementation uses excess space.

  29. front Queue • Same idea as like STACK, but has front and back back

  30. Comparison of the Two Methods • Both of them run in constant time per operation. • The vector version is likely to be faster. But it has two drawbacks: • The wraparound is a little confusing; • It might waste more space.

  31. Deque/Double-Ended Queue • A deque is a double-ended queue. • A deque is a little modification on the queue data structure, where access is given to both the ends. • Operations : addFront, addRear, removeFront, removeRear. • That is, a deque is especially optimized for pushing and popping elements at the beginning and end. As with vectors, storage management is handled automatically.

  32. Common errors (Page 561) • Do not delete the top node directly before adjusting the top of the stack pointer • Be aware of memory leaks • Access is constant time in both of these implementations.

More Related