Stacks CS 302 Data Structures Sections 5 1

  • Slides: 48
Download presentation
Stacks CS 302 – Data Structures Sections 5. 1, 5. 2, 6. 1, 6.

Stacks CS 302 – Data Structures Sections 5. 1, 5. 2, 6. 1, 6. 5

Warning • Although data structure concepts between this and last semesters will be the

Warning • Although data structure concepts between this and last semesters will be the same, there might be implementation differences. • Your answers in questions in quizzes and exams should be based on this semester’s (CS 302) implementations!

Definitions • Image. Type. h • Image. Type. cpp • Driver. cpp class specification

Definitions • Image. Type. h • Image. Type. cpp • Driver. cpp class specification class implementation application (client code)

Question • In object oriented programming, class implementation details are hidden from applications that

Question • In object oriented programming, class implementation details are hidden from applications that use the class. • Why?

What is a stack? • • • It is an ordered group of homogeneous

What is a stack? • • • It is an ordered group of homogeneous items. Items are added to and removed from the top of the stack LIFO property: Last In, First Out The last item added would be the first to be removed TOP OF THE STACK

Stack Implementations Array-based Linked-list-based

Stack Implementations Array-based Linked-list-based

Array-based Stacks template<class Item. Type> class Stack. Type { public: Stack. Type(int); void Make.

Array-based Stacks template<class Item. Type> class Stack. Type { public: Stack. Type(int); void Make. Empty(); bool Is. Empty() const; bool Is. Full() const; void Push(Item. Type); void Pop(Item. Type&); private: int top, max. Stack; Item. Type *items; }; dynamically allocated array

Array-based Stacks (cont’d) template<class Item. Type> Stack. Type<Item. Type>: : Stack. Type(int size) {

Array-based Stacks (cont’d) template<class Item. Type> Stack. Type<Item. Type>: : Stack. Type(int size) { top = -1; max. Stack = size; items = new Item. Type[max]; O(1) } template<class Item. Type> Stack. Type<Item. Type>: : ~Stack. Type() { delete [ ] items; } O(1)

Array-based Stacks (cont’d) template<class Item. Type> void Stack. Type<Item. Type>: : Make. Empty() {

Array-based Stacks (cont’d) template<class Item. Type> void Stack. Type<Item. Type>: : Make. Empty() { top = -1; } O(1)

Array-based Stacks (cont. ) template<class Item. Type> bool Stack. Type<Item. Type>: : Is. Empty()

Array-based Stacks (cont. ) template<class Item. Type> bool Stack. Type<Item. Type>: : Is. Empty() const { return (top == -1); } O(1) template<class Item. Type> bool Stack. Type<Item. Type>: : Is. Full() const { return (top == max. Stack-1); } O(1)

Push (Item. Type new. Item) • Function: Adds new. Item to the top of

Push (Item. Type new. Item) • Function: Adds new. Item to the top of the stack. • Preconditions: Stack has been initialized and is not full. • Postconditions: new. Item is at the top of the stack.

Stack overflow • The condition resulting from trying to push an element onto a

Stack overflow • The condition resulting from trying to push an element onto a full stack. if(!stack. Is. Full()) stack. Push(item);

Array-based Stacks (cont. ) template<class Item. Type> void Stack. Type<Item. Type>: : Push(Item. Type

Array-based Stacks (cont. ) template<class Item. Type> void Stack. Type<Item. Type>: : Push(Item. Type new. Item) { top++; items[top] = new. Item; } O(1)

Pop (Item. Type& item) • Function: Removes top. Item from stack and • •

Pop (Item. Type& item) • Function: Removes top. Item from stack and • • returns it in item. Preconditions: Stack has been initialized and is not empty. Postconditions: Top element has been removed from stack and item is a copy of the removed element.

Stack underflow • The condition resulting from trying to pop an empty stack. if(!stack.

Stack underflow • The condition resulting from trying to pop an empty stack. if(!stack. Is. Empty()) stack. Pop(item);

Array-based Stacks (cont. ) template<class Item. Type> void Stack. Type<Item. Type>: : Pop(Item. Type&

Array-based Stacks (cont. ) template<class Item. Type> void Stack. Type<Item. Type>: : Pop(Item. Type& item) { item = items[top]; O(1) top--; }

Templates • Templates allow the compiler to generate multiple versions of a class type

Templates • Templates allow the compiler to generate multiple versions of a class type by allowing parameterized types. • Compiler generates distinct class types and gives its own internal name to each of the types.

Compiling Templates • Cannot anymore compile Stack. Type. cpp separately from the application of

Compiling Templates • Cannot anymore compile Stack. Type. cpp separately from the application of the class (e. g. , driver. cpp) • Compiler needs to know the data type of the stack to instantiate the class! • Where can the compiler find this information?

Compiling Templates (cont’d) // Client code Stack. Type<int> my. Stack; Stack. Type<float> your. Stack;

Compiling Templates (cont’d) // Client code Stack. Type<int> my. Stack; Stack. Type<float> your. Stack; Stack. Type<Str. Type> another. Stack; my. Stack. Push(35); your. Stack. Push(584. 39);

Compiling Templates (cont’d) • Must compile Stack. Type. cpp and client code (e. g.

Compiling Templates (cont’d) • Must compile Stack. Type. cpp and client code (e. g. , driver. cpp) together! (1) Use “include” directive to include Stack. Type. cpp at the end of Stack. Type. h (2) “include” Stack. Type. h in client’s code (3) Compile client code

Linked-list-based Stacks template<class Item. Type> struct Node. Type<Item. Type> { Item. Type info; Node.

Linked-list-based Stacks template<class Item. Type> struct Node. Type<Item. Type> { Item. Type info; Node. Type<Item. Type>* next; };

Linked-list-based Stacks (cont’d) template<class Item. Type> struct Node. Type<Item. Type>; template<class Item. Type> class

Linked-list-based Stacks (cont’d) template<class Item. Type> struct Node. Type<Item. Type>; template<class Item. Type> class Stack. Type { public: Stack. Type(); ~Stack. Type(); void Make. Empty(); bool Is. Empty() const; bool Is. Full() const; void Push(Item. Type); void Pop(Item. Type&); private: Node. Type<Item. Type>* top. Ptr; };

Linked-list-based Stacks (cont’d) template<class Item. Type> Stack. Type<Item. Type>: : Stack. Type() { top.

Linked-list-based Stacks (cont’d) template<class Item. Type> Stack. Type<Item. Type>: : Stack. Type() { top. Ptr = NULL; O(1) } template<class Item. Type> void Stack. Type<Item. Type>: : Make. Empty() { Node. Type<Item. Type>* temp. Ptr; while(top. Ptr != NULL) { temp. Ptr = top. Ptr; top. Ptr = top. Ptr->next; delete temp. Ptr; } } O(N)

Linked-list-based Stacks (cont’d) template<class Item. Type> Stack. Type<Item. Type>: : ~Stack. Type() { Make.

Linked-list-based Stacks (cont’d) template<class Item. Type> Stack. Type<Item. Type>: : ~Stack. Type() { Make. Empty(); } O(N) template<class Item. Type> bool Stack. Type<Item. Type>: : Is. Empty() const { return(top. Ptr == NULL); } O(1)

Linked-list-based Stacks (cont’d) template<class Item. Type> bool Stack. Type<Item. Type>: : Is. Full() const

Linked-list-based Stacks (cont’d) template<class Item. Type> bool Stack. Type<Item. Type>: : Is. Full() const { Node. Type<Item. Type>* location; location = new Node. Type<Item. Type>; // test if(location == NULL) return true; else { O(1) delete location; return false; } }

Push (Item. Type new. Item) • Function: Adds new. Item to the top of

Push (Item. Type new. Item) • Function: Adds new. Item to the top of the stack. • Preconditions: Stack has been initialized and is not full. • Postconditions: new. Item is at the top of the stack.

Pushing on a non-empty stack

Pushing on a non-empty stack

Pushing on a non-empty stack (cont. ) • The order of changing the pointers

Pushing on a non-empty stack (cont. ) • The order of changing the pointers is important!

Special Case: pushing on an empty stack

Special Case: pushing on an empty stack

Function Push template <class Item. Type> void Stack. Type<Item. Type>: : Push(Item. Type Push

Function Push template <class Item. Type> void Stack. Type<Item. Type>: : Push(Item. Type Push item) { Node. Type<Item. Type>* location; location = new Node. Type<Item. Type>; location->info = new. Item; O(1) location->next = top. Ptr; top. Ptr = location; }

Pop (Item. Type& item) • Function: Removes top. Item from stack and • •

Pop (Item. Type& item) • Function: Removes top. Item from stack and • • returns it in item. Preconditions: Stack has been initialized and is not empty. Postconditions: Top element has been removed from stack and item is a copy of the removed element.

Popping the top element

Popping the top element

Popping the top element (cont. ) Need a temporary pointer !

Popping the top element (cont. ) Need a temporary pointer !

Special case: popping the last element on the stack temp. Ptr

Special case: popping the last element on the stack temp. Ptr

Function Pop template <class Item. Type> void Stack. Type<Item. Type>: : Pop(Item. Type& item)

Function Pop template <class Item. Type> void Stack. Type<Item. Type>: : Pop(Item. Type& item) Pop { Node. Type<Item. Type>* temp. Ptr; item = top. Ptr->info; temp. Ptr = top. Ptr; top. Ptr = top. Ptr->next; delete temp. Ptr; } O(1)

Comparing stack implementations Big-O Comparison of Stack Operations Operation Array Linked Implementation Constructor Make.

Comparing stack implementations Big-O Comparison of Stack Operations Operation Array Linked Implementation Constructor Make. Empty Is. Full Is. Empty Push Pop Destructor O(1) O(1) O(N) O(1) O(N)

Array-vs Linked-list-based Stack Implementations • Array-based implementation is simple but: – The size of

Array-vs Linked-list-based Stack Implementations • Array-based implementation is simple but: – The size of the stack must be determined when a stack object is declared. – Space is wasted if we use less elements. – We cannot "enqueue" more elements than the array can hold. • Linked-list-based implementation alleviates these problems but time requirements might increase.

Example using stacks: evaluate postfix expressions • Postfix notation is another way of writing

Example using stacks: evaluate postfix expressions • Postfix notation is another way of writing arithmetic • expressions. In postfix notation, the operator is written after the two operands. infix: 2+5 postfix: 2 5 + • Why using postfix notation? Precedence rules and parentheses are not required!

Example: postfix expressions (cont. ) Expressions are evaluated from left to right.

Example: postfix expressions (cont. ) Expressions are evaluated from left to right.

Postfix expressions: Algorithm using stacks (cont. )

Postfix expressions: Algorithm using stacks (cont. )

Exercise 15: Write the body for a client function that replaces each copy of

Exercise 15: Write the body for a client function that replaces each copy of an item in a stack with another item. Use the following specification. Replace. Item(Stack. Type& stack, Item. Type old. Item, Item. Type new. Item) Function: Replaces all occurrences of old. Item with new. Item. Precondition: stack has been initialized. Postconditions: Each occurrence of old. Item in stack has been replaced by new. Item. Order of other elements remains unchanged. Warning: you may not assume any knowledge of how the stack is implemented!

{ Stack temp. Stack 3 1 2 5 1 3 Item. Type item; Stack.

{ Stack temp. Stack 3 1 2 5 1 3 Item. Type item; Stack. Type temp. Stack; while (!Stack. Is. Empty()) { Stack. Pop(item); if (item==old. Item) temp. Stack. Push(new. Item); else temp. Stack. Push(item); } while (!temp. Stack. Is. Empty()) { temp. Stack. Pop(item); Stack. Push(item); } } Stack 3 old. Item = 2 5 new. Item = 5 1

{ Item. Type item; Stack. Type temp. Stack; while (!Stack. Is. Empty()) { Stack.

{ Item. Type item; Stack. Type temp. Stack; while (!Stack. Is. Empty()) { Stack. Pop(item); if (item==old. Item) temp. Stack. Push(new. Item); else temp. Stack. Push(item); } while (!temp. Stack. Is. Empty()) { temp. Stack. Pop(item); Stack. Push(item); } } What are the time requirements using big-O? O(N)

Exercises 19, 20

Exercises 19, 20

Exercises 19, 20

Exercises 19, 20

Exercise 20 small large

Exercise 20 small large

Exercise 20 (cont’d) etc.

Exercise 20 (cont’d) etc.

Exercise 20 (cont’d)

Exercise 20 (cont’d)