Stacks and Queues
Worklists 1
Worklists A family of data structures that o can hold elements and o give us a way to get them back add an element retrieve an element to the worklist from the worklist Client view of a data structure The client has no idea how it is implemented 2
add an element retrieve an element to the worklist from the worklist Worklists A family of data structures that o can hold elements and o give us a way to get them back Examples o to-do list o cafeteria line o suspended processes in an OS, … Pervasively used in computer science o This will be our first “real” data structures 3
add an element retrieve an element to the worklist from the worklist Concrete Worklists Adding an element simply puts it in the worklist But which element should we get back? Several options o Stacks : retrieve the element inserted most recently The LIFO data structure L a s t I n F i r s t O u t o Queues : retrieve the element that has been there longest The FIFO data structure F i r s t I n F i r s t O u t o Priority queues: retrieve the most “interesting” element We will talk about them later on 4
add an element retrieve an element to the worklist from the worklist The Worklist Interface Turn the idea of a worklist into a data structure o Develop an interface for an abstract data type Types We will generalize this later on o Elements in the worklist: string o Worklist itself: wl_t This is the abstract type of worklists A pointer type Operations o add an element: wl_add o retrieve an element: wl_retrieve o create a new worklist: wl_new There is no wl_full. We are considering o check if the worklist is empty: wl_empty unbounded worklists we cannot retrieve anything from an empty worklist! can hold arbitrarily many elements 5
add an element retrieve an element to the worklist from the worklist Worklist Interface Operands and contracts o add an element: wl_add Takes in a worklist and an element Worklist is not empty as a result o retrieve an element: wl_retrieve Takes in a worklist, returns an element Worklist must not be empty a bunch of NULL-checks o create a new worklist: wl_new Takes in nothing, returns an empty worklist o check if the worklist is empty: wl_empty Takes in a worklist, returns a boolean 6
add an element retrieve an element to the worklist from the worklist The Worklist Interface Worklist Interface // typedef ______* wl_t; bool wl_empty(wl_t W) /*@requires W != NULL; @*/ ; This will be a template for the wl_t wl_new() /*@ensures \result != NULL; @*/ concrete worklists we will be /*@ensures wl_empty(\result); @*/ ; working with void wl_add(wl_t W, string x) /*@requires W != NULL; @*/ stacks and queues /*@ensures !wl_empty(W); @*/ ; o We will never use this interface string wl_retrieve(wl_t W) o We will use instances for stacks /*@requires W != NULL; @*/ /*@requires !wl_empty(W); @*/ ; and for queues What 7
Stacks 8
Stacks A worklist where we retrieve the last inserted element L ast I n F irst O ut o Like a stack of books pop an element push an element from the stack onto the stack Traditional name of operations top o push (= add) on top o pop (= retrieve) from top 9
Stacks A worklist where we pop the last element pushed F irst I n L ast O ut If we push push pop o “hello” then “brave” then “world” and then pop, we get o “world” “world” and then pop again, we get “brave” o “brave” “hello” and pop once more, we get o “hello” at this point the stack is empty 10
push pop The Stack Interface Stack Interface // typedef ______* stack_t; bool stack_empty(stack_t S) // O(1) This is the worklist interface /*@requires S != NULL; @*/ ; with the names changed stack_t stack_new() // O(1) /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/ ; We are providing complexity void push(stack_t S, string x) // O(1) /*@requires S != NULL; @*/ bounds in the interface /*@ensures !stack_empty(S); @*/ ; o We promise the stack library string pop(stack_t S) // O(1) will implement the operations to /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ; have these cost all stack operations have constant What cost 11
push pop The Stack Interface Stack Interface Since stacks implement a // typedef ______* stack_t; L ast I n F irst O ut policy, bool stack_empty(stack_t S) // O(1) what about adding /*@requires S != NULL; @*/ ; stack_t stack_new() // O(1) //@ensures(string_equal(pop(S), x); /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/ ; as a postcondition to push? void push(stack_t S, string x) // O(1) /*@requires S != NULL; @*/ pop(S) changes S! /*@ensures !stack_empty(S); @*/ ; o Running with and without string pop(stack_t S) // O(1) /*@requires S != NULL; @*/ contracts enabled could produce /*@requires !stack_empty(S); @*/ ; different outcomes o This contract is not pure What o The C0 compiler has a purity check that catches this 12
Stack Interface Using only // typedef ______* stack_t; functions from the Peeking into a Stack bool stack_empty(stack_t S) // O(1) stack interface /*@requires S != NULL; @*/ ; stack_t stack_new() // O(1) /*@ensures \result != NULL; @*/ Write a client function that returns the top /*@ensures stack_empty(\result); @*/ ; element of the stack without removing it void push(stack_t S, string x) // O(1) /*@requires S != NULL; @*/ o We can do that only if the stack is not empty /*@ensures !stack_empty(S); @*/ ; string pop(stack_t S) // O(1) This is a precondition /*@requires S != NULL; @*/ o Simply pop the stack in a variable, /*@requires !stack_empty(S); @*/ ; push the element back, and return the value of the variable string peek(stack_t S) //@requires S != NULL; //@requires !stack_empty(S); { string x = pop(S); push(S, x); return x; } 13
Stack Interface // typedef ______* stack_t; Peeking into a Stack bool stack_empty(stack_t S) // O(1) /*@requires S != NULL; @*/ ; stack_t stack_new() // O(1) /*@ensures \result != NULL; @*/ Write a client function that returns the top /*@ensures stack_empty(\result); @*/ ; element of the stack without removing it void push(stack_t S, string x) // O(1) /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ; 1. string peek(stack_t S) string pop(stack_t S) // O(1) 2. //@requires S != NULL; /*@requires S != NULL; @*/ 3. //@requires !stack_empty(S); /*@requires !stack_empty(S); @*/ ; 4. { string x = pop(S); 5. push(S, x); 6. return x; 7. 8. } Is this code safe? o stack_empty(S): o pop(S): o push(S, x) S != NULL by line 2 S != NULL by line 2 S != NULL by line 2 !stack_empty(S) by line 3 14
Stack Interface // typedef ______* stack_t; Peeking into a Stack bool stack_empty(stack_t S) // O(1) /*@requires S != NULL; @*/ ; stack_t stack_new() // O(1) /*@ensures \result != NULL; @*/ Write a client function that returns the top /*@ensures stack_empty(\result); @*/ ; element of the stack without removing it void push(stack_t S, string x) // O(1) /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ; string peek(stack_t S) string pop(stack_t S) // O(1) //@requires S != NULL; /*@requires S != NULL; @*/ //@requires !stack_empty(S); /*@requires !stack_empty(S); @*/ ; { string x = pop(S); push(S, x); return x; } What is the asymptotic complexity? o pop(S): O(1) o push(S, x): O(1) o return x O(1) Total: O(1) Complexity guarantees in the interface allow us to determine the cost of client functions 15
Stack Interface Using only // typedef ______* stack_t; functions from the Peeking into a Stack bool stack_empty(stack_t S) // O(1) stack interface /*@requires S != NULL; @*/ ; stack_t stack_new() // O(1) /*@ensures \result != NULL; @*/ Write a client function that returns the top /*@ensures stack_empty(\result); @*/ ; element of the stack without removing it void push(stack_t S, string x) // O(1) /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ; What about this implementation? string pop(stack_t S) // O(1) /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ; string peek(stack_t S) //@requires S != NULL; //@requires !stack_empty(S); { return S->data[S->top]; } o It assumes stacks are implemented as structs with a data and a top field but we don’t know anything about how stacks are implemented! all we have is an interface o This violates the interface of the stack library 16
Stack Interface // typedef ______* stack_t; The Size of a Stack bool stack_empty(stack_t S) // O(1) /*@requires S != NULL; @*/ ; stack_t stack_new() // O(1) /*@ensures \result != NULL; @*/ Write a client function that returns the /*@ensures stack_empty(\result); @*/ ; number of elements in a stack void push(stack_t S, string x) // O(1) /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ; string pop(stack_t S) // O(1) /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ; 17
Recommend
More recommend