1 CSC 222: Computer Programming II Spring 2004 Stacks and recursion  stack ADT  push, pop, top, empty, size  vector-based implementation, library 

Slides:



Advertisements
Similar presentations
Stack & Queues COP 3502.
Advertisements

Stacks & Their Applications COP Stacks  A stack is a data structure that stores information arranged like a stack.  We have seen stacks before.
The unorganized person’s data structure
Lecture 5 Sept 15 Goals: stacks Implementation of stack applications Postfix expression evaluation Convert infix to postfix.
Stacks CS 3358 – Data Structures. What is a stack? It is an ordered group of homogeneous items of elements. Elements are added to and removed from the.
Stack and Queue Dr. Bernard Chen Ph.D. University of Central Arkansas.
Topic 15 Implementing and Using Stacks
Lecture 7 Sept 16 Goals: stacks Implementation of stack applications Postfix expression evaluation Convert infix to postfix.
Stacks.
Lecture 6 Feb 12 Goals: stacks Implementation of stack applications Postfix expression evaluation Convert infix to postfix.
Stacks. 2 What is a stack? A stack is a Last In, First Out (LIFO) data structure Anything added to the stack goes on the “top” of the stack Anything removed.
Stacks (Revised and expanded from CIT 591). What is a stack? A stack is a Last In, First Out (LIFO) data structure Anything added to the stack goes on.
Stacks. 2 What is a stack? A stack is a Last In, First Out (LIFO) data structure Anything added to the stack goes on the “top” of the stack Anything removed.
Stacks. What is a stack? A stack is a Last In, First Out (LIFO) data structure Anything added to the stack goes on the “top” of the stack Anything removed.
Topic 15 Implementing and Using Stacks
The Stack and Queue Types Lecture 10 Hartmut Kaiser
Object Oriented Data Structures
1 CSC 222: Computer Programming II Spring 2005 Stacks and recursion  stack ADT  push, pop, peek, empty, size  ArrayList-based implementation, java.util.Stack.
Implementing Stacks Ellen Walker CPSC 201 Data Structures Hiram College.
1 Stacks Chapter 4 2 Introduction Consider a program to model a switching yard –Has main line and siding –Cars may be shunted, removed at any time.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 12: Recursion Problem Solving, Abstraction, and Design using C++
Computer Science Department Data Structure & Algorithms Problem Solving with Stack.
Modular Programming Chapter Value and Reference Parameters computeSumAve (x, y, sum, mean) ACTUALFORMAL xnum1(input) ynum2(input) sumsum(output)
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved Stacks.
Stacks 1. Stack  What is a stack? An ordered list where insertions and deletions occur at one end called the top. Also known as last-in-first-out (LIFO)
COP3530 Data Structures600 Stack Stack is one the most useful ADTs. Like list, it is a collection of data items. Supports “LIFO” (Last In First Out) discipline.
Recursion Textbook chapter Recursive Function Call a recursive call is a function call in which the called function is the same as the one making.
224 3/30/98 CSE 143 Recursion [Sections 6.1, ]
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
© 2004 Goodrich, Tamassia Stacks. © 2004 Goodrich, Tamassia Stacks2 Abstract Data Types (ADTs) An abstract data type (ADT) is an abstraction of a data.
Stacks. A stack is a data structure that holds a sequence of elements and stores and retrieves items in a last-in first- out manner (LIFO). This means.
Introduction to Stacks Chapter 2. Objectives Introduce abstract data types. Discuss implementation types. – Static – Dynamic – Contiguous Introduce the.
1 C++ Classes and Data Structures Jeffrey S. Childs Chapter 2 Overloaded Operators, Class Templates, and Abstraction Jeffrey S. Childs Clarion University.
Implementing Subprograms What actions must take place when subprograms are called and when they terminate? –calling a subprogram has several associated.
1 CSC 321: Data Structures Fall 2012 Lists, stacks & queues  Collection classes: ─List (ArrayList, LinkedList), Set (TreeSet, HashSet), Map (TreeMap,
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved Stacks.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved Stacks.
1 Chapter 2 C++ Syntax and Semantics, and the Program Development Process.
Data Structures & Algorithms
1 Data Structures CSCI 132, Spring 2014 Lecture 6 Applications using Stacks.
12/23/2015Engineering Problem Solving with C++, second edition, J. Ingber 1 Engineering Problem Solving with C++, Etter/Ingber Chapter 9 An Introduction.
Copyright © Curt Hill Stacks An Useful Abstract Data Type.
1 CSC 222: Computer Programming II Spring 2004  classes and objects  abstract data types, classes and objects  using existing classes, #include, member.
1 Becoming More Effective with C++ … Day Two Stanley B. Lippman
Fall 2006 METU EEEEE 441 S. Ece (GURAN) SCH MIDT EE 441 Data Structures Lecture 6 Stacks and Queues.
11/07/141 Abstract Data Types (ADTs) An abstract data type (ADT) is an abstraction of a data structure An ADT specifies: –Data stored –Operations on the.
1 Data Structures CSCI 132, Spring 2016 Notes 6 Applications using Stacks.
Copyright 2006 Addison-Wesley Brief Version of Starting Out with C++ Chapter 5 Looping.
1 CSC 533: Programming Languages Spring 2014 Subprogram implementation  subprograms (procedures/functions/subroutines)  subprogram linkage  parameter.
Click to edit Master text styles Stacks Data Structure.
1 Data Structures and Algorithms Stack. 2 The Stack ADT Introduction to the Stack data structure Designing a Stack class using dynamic arrays Linked Stacks.
CSC 143 P 1 CSC 143 Recursion [Chapter 5]. CSC 143 P 2 Recursion  A recursive definition is one which is defined in terms of itself  Example:  Compound.
1 Data Structures and Algorithms Stack. 2 The Stack ADT Introduction to the Stack data structure Designing a Stack class using dynamic arrays Linked Stacks.
1 Data Structures CSCI 132, Spring 2016 Notes_ 5 Stacks.
Stacks Stacks.
Revised based on textbook author’s notes.
Homework 4 questions???.
Stacks Chapter 4.
5.1 The Stack Abstract Data Type
Stacks.
CSC 533: Programming Languages Spring 2015
Stacks.
Stacks Data structure Elements added, removed from one end only
Topic 15 Implementing and Using Stacks
Jordi Cortadella and Jordi Petit Department of Computer Science
Stacks Chapter 5.
CSC 533: Programming Languages Spring 2018
CSC 533: Programming Languages Spring 2019
Chapter 7 (continued) © 2011 Pearson Addison-Wesley. All rights reserved.
5.1 The Stack Abstract Data Type
Presentation transcript:

1 CSC 222: Computer Programming II Spring 2004 Stacks and recursion  stack ADT  push, pop, top, empty, size  vector-based implementation, library  application: parenthesis/delimiter matching  run-time stack

2 Lists & stacks list ADT DATA:sequence of items OPERATIONS:add item, look up item, delete item, check if empty, get size, … e.g., array, vector, DeckOfCards, CaveMaze, List, SortedList stack ADT  a stack is a special kind of (simplified) list  can only add/delete/look at one end (commonly referred to as the top) DATA:sequence of items OPERATIONS:push on top, peek at top, pop off top, check if empty, get size these are the ONLY operations allowed on a stack — stacks are useful because they are simple, easy to understand — each operation is O(1)

3 Stack examples  PEZ dispenser  pile of cards  cars in a driveway  function activation records (later) a stack is also known as  push-down list  last-in-first-out (LIFO) list top 1 2 pop: removes item at top top top: returns item at top  top push: adds item at the top 4

4 Stack exercise start with empty stack PUSH 1 PUSH 2 PUSH 3 TOP PUSH 4 POP TOP PUSH 5

5 stack implementation template class stack { public: stack() { /* does nothing */ } void push(const Type & item) { elements.push_back(item); } void pop() { elements.pop_back(); } Type top() & const { return elements.back(); } bool empty() const { return (elements.size() == 0); } int size() const { return elements.size(); } private: vector elements; }; recall that the vector class provides member functions for all of these push_back pop_back back size we could simply use a vector whenever we want stack behavior better yet, define a stack class in terms of vector

6 In-class exercise stack numStack; int num; while (cin >> num) { numStack.push(num); } while ( !numStack.empty() ) { cout << numStack.top() << endl; numStack.pop(); } what does this code do? create a C++ project  copy stack.h and pushy.cpp and add to the projectstack.hpushy.cpp  test it stack numStack1, numStack2; int num; while (cin >> num) { numStack1.push(num); } while ( !numStack1.empty() ) { numStack2.push(numStack1.top()); numStack1.pop(); } while ( !numStack2.empty() ) { cout << numStack2.top() << endl; numStack2.pop(); } now what?

7 class since a stack is a common data structure, a predefined C++ library exists #include the standard stack class has all the same member functions as our implementation void push(const TYPE & item); // adds item to top of stack void pop();// removes item at top of stack TYPE & top() const;// returns item at top of stack bool empty() const;// returns true if stack is empty int size() const;// returns size of stack replace "stack.h" with in your program and verify it works

8 Stack application consider mathematical expressions such as the following  a compiler must verify such expressions are of the correct form (A * (B + C) )((A * (B + C)) + (D * E)) how do you make sure that parentheses match? common first answer:  count number of left and right parentheses  expression is OK if and only if # left = # right (A * B) + )C( more subtle but correct answer:  traverse expression from left to right  keep track of # of unmatched left parentheses  if count never becomes negative and ends at 0, then OK

9 Parenthesis matching #include using namespace std; int main() { string expression; cout << "Enter the expression to check: "; getline(cin, expression); int openCount = 0; for (int i = 0; i < expression.length(); i++) { if (expression[i] == '(') { openCount++; } else if (expression[i] == ')') { openCount--; if (openCount < 0) { cout << "INVALID: unmatched ')'" << endl; exit(1); } if (openCount == 0) { cout << "VALID expression" << endl; } else { cout << "INVALID: unmatched '('" << endl; } return 0; } openCount keeps track of unmatched left parens as the code traverses the string, the counter is incremented on '(' decremented on ')' openCount must stay non- negative and end at 0

10 Delimiter matching now, let's generalize to multiple types of delimiters (A * [B + C] ){(A * [B + C]) + [D * E]} does a single counter work? recursive solution:  traverse the expression from left to right  if you find a left delimiter, recursively traverse until find the matching delimiter stack-based solution:  start with an empty stack of characters  traverse the expression from left to right if next character is a left delimiter, push onto the stack if next character is a right delimiter, must match the top of the stack how about separate counters for each type of delimiter?

11 Delimiter matching int main() { string expression; cout << "Enter the expression to check: "; getline(cin, expression); stack delimiters; for (int i = 0; i < expression.length(); i++) { if (IsLeftDelimiter(expression[i])) { delimiters.push(expression[i]); } else if (IsRightDelimiter(expression[i])) { if (!delimiters.empty() && delimiters.top() == MatchingDelimiter(expression[i])) { delimiters.pop(); } else { cout << "INVALID: unmatched " << expression[i] << endl; exit(1); } if (delimiters.empty()) { cout << "VALID expression" << endl; } else { cout << "INVALID: unmatched" << delimters.top() << endl; } return 0; } here, defined abstract functions for categorizing delimiters note natural correspondence to the simpler version

12 Delimiter matching (cont.) const string LEFT = "([{"; const string RIGHT = ")]}";... bool IsLeftDelimiter(char ch) { return (LEFT.find(ch) != string::npos); } bool IsRightDelimiter(char ch) { return (RIGHT.find(ch) != string::npos); } char MatchingDelimiter(char ch) { if (IsLeftDelimiter(ch)) { int index = LEFT.find(ch); return RIGHT[index]; } else if (IsRightDelimiter(ch)) { int index = RIGHT.find(ch); return LEFT[index]; } else { return '?'; } to avoid global modifications whenever a new pair of delimiters is added: use global strings to store delimiters of each type (keep data in parallel) to see if a char is a delimiter, search these strings using find to get the matching delimiter, find the char then access the char in the other parallel string

13 Reverse Polish evaluating Reverse Polish (postfix) expressions  note: if entering expressions into a calculator in postfix, don't need parens  this format was used by early HP calculators (& some models still allow the option)  *  (1 + 2) * * +  1 + (2 * 3) to evaluate a Reverse Polish expression:  start with an empty stack that can store numbers  traverse the expression from left to right  if next char is an operand (number or variable), push on the stack  if next char is an operator (+, -, *, /, …), 1.pop 2 operands off the top of the stack 2.apply the operator to the operands 3.push the result back onto the stack  when done, the value of the expression is on top of the stack

14 Run-time stack when a function is called in C++ (or any language):  suspend the current execution sequence  allocate space for parameters, locals, return value, …  transfer control to the new function when the function terminates:  deallocate parameters, locals, …  transfer control back to the calling point (& possibly return a value) note: functions are LIFO entities  main is called first, terminates last  if main calls Foo and Foo calls Bar, then Bar terminates before Foo which terminates before main  a stack is a natural data structure for storing information about function calls and the state of the execution

15 Run-time stack (cont.) an activation record stores info (parameters, locals, …) for each invocation of a function  when the function is called, an activation record is pushed onto the stack  when the function terminates, its activation record is popped  note that the currently executing function is always at the top of the stack void Foo(int a) { a++; cout << "Foo " << a << endl; } int main() { int x = 12; Foo(x); cout << "main " << x << endl; return 0; } main: x = automatically start with main main: x = when Foo called, push Foo: a = main: x = when Foo done, pop when main done, pop & end

16 Another example void Bar(int z) { z--; cout << "Bar " << z << end;' } void Foo(int a) { a++; cout << "Foo " << a << endl; Bar(a + 10); } int main() { int x = 12; Foo(x); cout << "main1 " << x << endl; Bar(x); cout << "main2 " << x << endl; return 0; } run time stack behavior?

17 Recursive example void Recurse(int a, int b) { if (a >= b) { return 0; } else { return 1 + Recurse(a+1, b); } int main() { int val = Recurse 1, 4); cout << "main " << val << endl; return 0; } recursive functions are treated just like any other functions  when a recursive call is made, an activation record for the new instance is pushed on the stack  when terminates (i.e., BASE CASE), pop off activation record & return value Recurse: a = 1 b = 4... main: val = ?... Recurse: a = 2 b = 4... Recurse: a = 3 b = 4... Recurse: a = 4 b = 4... returns 0returns 1+0 = 1 returns 1+1 = 2 returns 1+2 = 3 displays "main 3"

18 Programming language implementation note: function calls are not the only predictable (LIFO) type of memory  blocks behave like unnamed functions, each is its own environment for (int i = 0; i < 10; i++) { int sum = 0; if (i % 3 == 0) { int x = i*i*i; sum = sum + x; } even within a function or block, variables can be treated as LIFO int x;... int y; for most programming languages, predictable (LIFO) memory is allocated/deallocated/accessed on a run-time stack

19 In-class exercise copy the following files from the ~davereed/csc222/Code directory: mergeDemo.cppmergeDemo.cpp Sorts.h Die.h Die.cppSorts.hDie.hDie.cpp build a project and test merge sort on various list sizes to visualize the run-time stack:  modify the recursive MergeSort function so that it prints a message at the beginning and end (specifying the range being sorted) PUSH merge 0 9. POP merge 0 9  add a GLOBAL! counter to Sorts.h and keep track of the number of recursive calls (& display along with PUSH message)