TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 2 J. Maluszynski, IDA, Linköpings Universitet, 2006. abc cba a b c top Operations: d . . . d . . . Top(S) returns the top element of stack S Pop(S) removes and returns the top element of S Push(S; x) adds x on the top of S MakeEmptyStack() creates a new, empty stack IsEmptyStack(S) returns true iff S is empty TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 1 top d . . . or an error code, if S is empty or an error code, if S is empty J. Maluszynski, IDA, Linköpings Universitet, 2006. 1 n f act (n if n = 0 1) if n > 0 Store intermediate result for each recursion step on a stack S: f act (3) = 3 f act (2) Remember 3 until f act (2) is computed: Push(S; 3) f act (2) = 2 f act (1) Remember 2 until f act (1) is computed: Push(S; 2) f act (1) = 1 f act (0) Remember 1 until f act (0) is computed: Push(S; 1) f act (0) = 1; f act (3) = 1 Pop(S) Pop(S) Pop(S) J. Maluszynski, IDA, Linköpings Universitet, 2006. Sequences of data items appear in many applications; ! How to represent them in memory? ! What are typical and specific operations ? (define ADTs) ! How to implement them? ADT Stack TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . ) space consumption is O(n) Page 3 J. Maluszynski, IDA, Linköpings Universitet, 2006. Typical applications of ADT Stack Implementation of recursive procedures, Evaluation of arithmetic expressions, Checking correctness of parantheses nesting (e.g. XML tags validation) [Goodrich/Tamassia 5.1] – important applications (recursion, evaluation of expressions) – representation in contiguous memory, – representation in linked memory ADT Queue and its representations Definition: f act (n) = Overview: Stacks, Queues, Lists [Goodrich/Tamassia 5.2] – in contiguous memory – in linked memory ADT Array List ADT Node List Page 4 Computing Factorial ADT Stack (Last In First Out) top TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . [Goodrich/Tamassia 6.1] [Goodrich/Tamassia 6.2] TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 6 J. Maluszynski, IDA, Linköpings Universitet, 2006. TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Tail Recursion Both recursive calls can be eliminated: stack not needed: everything on stack will be discarded tail-recursive functions can be rewritten using iteration The recursive call in fact is not tail-recursive: function fact (integer n) : integer if n = 0 then return 1 else f n f act (n 1); return f The first instruction after returning from the recursive call is multiplication ! n must be kept on stack Page 5 J. Maluszynski, IDA, Linköpings Universitet, 2006. function binarySearch ( T [a::b], int K) : int (1) if a > b then return 1 middle b(a + b)=2c if K = T [middle] then return middle else if K < T [middle] then f was: return binarySearch(T [a::middle 1]; K ) g b middle 1 else fK > T [middle]g f was: return binarySearch(T [a::middle + 1]; K ) g a middle + 1 goto (1) TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Stack application: Implementing recursive procedures Tail-recursive function function fact (integer n) : integer if n = 0 then return 1 else f n f act (n 1); return f Consider binarySearch: for each function call: push arguments, local variables, return address (which form the function’s activation record), enter the procedure pop and discard the arguments go to the return address Page 7 (free) 1 return address 1 fact(1) 2 return address 2 fact(2) 3 return address fact(3) 3 ... The programming language implementation (compiler + run-time system) uses internally a stack to keep track of recursion. on exit from the call: J. Maluszynski, IDA, Linköpings Universitet, 2006. Tail Recursion Elimination A recursive call is tail-recursive iff the first instruction after returning from it is return. TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 8 Run-time stack immediately before calling fact(0) function binarySearch ( T [a::b], int K) : int if a > b then return 1 middle b(a + b)=2c if K = T [middle] then return middle else if K < T [middle] then return binarySearch(T [a::middle 1]; K ) else fK > T [middle]g return binarySearch(T [middle + 1::b]; K ) Both recursive calls are tail-recursive. J. Maluszynski, IDA, Linköpings Universitet, 2006. TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 10 J. Maluszynski, IDA, Linköpings Universitet, 2006. Implementing a Stack in Contiguous Memory (1) S . . . x0 xk . . . . . . x0 0 S 1]) function MakeEmptyStack() : pointer S NewCell(StackListHead) ptop(S) Λ return S procedure Push( pointer S, dataitem x ) if Length(S) = n then error else A(S)[Length(S)] x Length(S) Length(S)+1 procedure Push( pointer S, dataitem x ) y NewCell(StackListItem) In f o(y) x Next (y) ptop(S) ptop(S) y function Pop( pointer S ) : dataitem if Length(S) = 0 then error else Length(S) Length(S) 1 return A(S)[Length(S)] ... n-1 A Length n Length(S) = k + 1 <= n Page 9 J. Maluszynski, IDA, Linköpings Universitet, 2006. x2 Info S Info Next – call to NewCell in each Push operation and to FreeCell in each Pop operation Page 11 Implementing a Stack in Contiguous Memory (2) f act can be rewritten by introducing a help function: function Top( pointer S ) : dataitem if Length(S) = 0 then error else return A(S)[Length(S) 1] f act2 is tail-recursive. ) space consumption after recursion elimination will be O(1) x0 Next function Pop( pointer S ) : dataitem if ptop(S) = Λ then error else y ptop(S) x In f o(y) ptop(S) Next (y) FreeCell(y) return x Tail-recursive Factorial Function function fact2 (integer n, integer f ) : integer if n = 0 then return f else return f act2(n 1; n f ) Info ptop J. Maluszynski, IDA, Linköpings Universitet, 2006. function fact (integer n) : integer return f act2(n; 1) x1 Next + maximum size need not be known in advance TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 12 Implementing a Stack in Linked Memory function MakeEmptyStack() : pointer S NewCell(StackTableHead) A(S) NewCell(table<dataitem> [0::n Length(S) 0 return S xk TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . function IsEmptyStack( pointer S ) : boolean return Length(S) = 0 All operations take O(1) time. J. Maluszynski, IDA, Linköpings Universitet, 2006. TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 14 J. Maluszynski, IDA, Linköpings Universitet, 2006. Implementing a Queue by a Ring Buffer/Circular Array . . . x2 x3 TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . x0 Info A x1 Next Info Next x2 Info Next n-1 Q S J. Maluszynski, IDA, Linköpings Universitet, 2006. Implementing a Queue in Linked Memory x0 x1 0 Page 16 Back Front pFront pBack Java code for the Queue operations: see course book, [Goodrich/Tamassia, Section 5.2.3] Length = k < n+1 + maximum size need not be known in advance Back = index of last available cell; Front = index of the first element Length or Size to control overflow: Size = (n + pointer pBack allows Enqueue to run in O(1) time (without pBack: need to traverse the entire list F + B) mod n ) needs Θ(k) time) – overhead for NewCell in Enqueue, for FreeCell in Dequeue Pseudocode for the Queue operations: [Goodrich/Tamassia, 5.2.2] TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 13 J. Maluszynski, IDA, Linköpings Universitet, 2006. ADT Queue (First In First Out) TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 15 J. Maluszynski, IDA, Linköpings Universitet, 2006. Examples of Ring Buffer Queue Operations last first B Enqueue(a) . . . abc a b c ... F Operations: Front(Q) returns the first element of Q Dequeue(Q) removes and returns the first element of Q Enqueue(Q; x) adds x at the end of Q MakeEmptyQueue() creates a new, empty queue IsEmptyQueue(Q) returns true iff Q is empty Typical application of ADT Queue: Serving requests in incoming order. Did you try to book a SAS ticket by phone? B Dequeue Enqueue(d) d B B F B B b F F B B c F Dequeue a F Enqueue(c) b Enqueue(b) a d F c b Dequeue c F B Dequeue F TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 18 J. Maluszynski, IDA, Linköpings Universitet, 2006. TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . ADT Array List ADT List (2) Domain: lists Update operations J. Maluszynski, IDA, Linköpings Universitet, 2006. insertFirst(x) insert a new element x as the first element of L, return the Operations on a vector S size() returns jSj isEmpty() returns true if jSj = 0 and false otherwise elemAtRank(i) returns S[i]; error if i 0 or i size() 1 insertAtRank(i x) inserts x as a new element at rank i: increases the size; < > ; error if i < 0 or i > size() removeAtRank(i) removes and returns the i-th element of S: decreases the size; error if i < 0 or i > size() Page 20 1 position of x. insertLast(x) insert a new element x as the last element of L, return the position of x. insertBefore( p x) insert a new element x before position p of L, return the ; position of x. insertAfter( p x) insert a new element x before position p of L, return the ; position of x. remove( p) remove from L and return the element at position p of L, return the position of x. TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 17 J. Maluszynski, IDA, Linköpings Universitet, 2006. TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 19 J. Maluszynski, IDA, Linköpings Universitet, 2006. ADT Node List (1) Lists A list L is a sequence of elements hx0; :::; xn 1 i Domain: lists size or length jLj = n empty list hi with length 0 Selection by index i (sometimes called rank): selects the i-th element, xi where i is an integer in the range 0::(n 1); Selection by actual position, e.g. first element of L or last, next, prev,... ! ADT Array List: using rank ! ADT Node List: using position [Goodrich, Tamassia 6.1] [Goodrich, Tamassia 6.2] Position abstracts from indexing. Operations on a list L size(L) returns jLj isEmpty() returns true if jSj = 0 and false otherwise first() returns the position of the first element of L; error if L is empty last() returns the position of the last element of L; error if L is empty prev( p) returns the position of the element of L preceding p ; error if p is the first position. next( p) returns the position of the element of L following p ; error if p is the last position. ...cont. next slide TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 22 J. Maluszynski, IDA, Linköpings Universitet, 2006. Singly Linked Lists TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . J. Maluszynski, IDA, Linköpings Universitet, 2006. Insertion in a Doubly Linked List ...... Info Info x0 x2 Prev Next L Page 24 Prev Info x3 ...... Prev Next Next P P Insertion Insertion: L P ...... Deletion Info Info x0 x2 Prev Next Prev Info x3 ...... Prev Next Next Info x1 P Prev L Next P TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Page 21 J. Maluszynski, IDA, Linköpings Universitet, 2006. Implementing ADT Vector, ADT List TDDB56 DALGOPT-D TDDB57 DALG-C – Lecture 3: Stacks, Queues, Lists . Doubly Linked Lists Contiguous memory representation: Singly linked lists: see next slide. – positions implemented as pointers – Analyze time complexity of the operations. – prev, insert Before require list traversal. Doubly linked lists: see below. Info Info x0 x1 Prev Next elements stored in a table/ array (e.g. Dynamic Vectors Lecture 2). – elem retrieval operations in O(1); – what about other operations? Page 23 D Prev Next (pFront) (pBack) Prev Info x2 Next Prev Next J. Maluszynski, IDA, Linköpings Universitet, 2006.