Question? Leave a message!




Stacks

Stacks
ECE 250 Algorithms and Data Structures Stacks Douglas Wilhelm Harder, M.Math. LEL Department of Electrical and Computer Engineering University of Waterloo Waterloo, Ontario, Canada ece.uwaterloo.ca dwharderalumni.uwaterloo.ca © 20062013 by Douglas Wilhelm Harder. Some rights reserved.Stacks 2 Outline 3.2 This topic discusses the concept of a stack: – Description of an Abstract Stack – List applications – Implementation – Example applications • Parsing: XHTML, C++ • Function calls • ReversePolish calculators • Robert’s Rules – Standard Template LibraryStacks 3 Abstract Stack 3.2.1 An Abstract Stack (Stack ADT) is an abstract data type which emphasizes specific operations: – Uses a explicit linear ordering – Insertions and removals are performed individually – Inserted objects are pushed onto the stack – The top of the stack is the most recently object pushed onto the stack – When an object is popped from the stack, the current top is erasedStacks 4 Abstract Stack 3.2.1 Also called a lastin–firstout (LIFO) behaviour – Graphically, we may view these operations as follows: There are two exceptions associated with abstract stacks: – It is an undefined operation to call either pop or top on an empty stackStacks 5 Applications 3.2.2 Numerous applications: – Parsing code: • Matching parenthesis • XML (e.g., XHTML) – Tracking function calls – Dealing with undo/redo operations – ReversePolish calculators – Assembly language The stack is a very simple data structure – Given any problem, if it is possible to use a stack, this significantly simplifies the solutionStacks 6 Stack: Applications 3.2.2 Problem solving: – Solving one problem may lead to subsequent problems – These problems may result in further problems – As problems are solved, your focus shifts back to the problem which lead to the solved problem Notice that function calls behave similarly: – A function is a collection of code which solves a problem Reference: Donald KnuthStacks 7 Implementations 3.2.3 We will look at two implementations of stacks: The optimal asymptotic run time of any algorithm is Q(1) – The run time of the algorithm is independent of the number of objects being stored in the container – We will always attempt to achieve this lower bound We will look at – Singly linked lists – Oneended arraysStacks 8 LinkedList Implementation 3.2.3.1 Operations at the front of a singly linked list are all Q(1) st th Front/1 Back/n Find Q(1)Q(1) Insert Q(1)Q(1) EraseQ(1)Q(n) The desired behaviour of an Abstract Stack may be reproduced by performing all operations at the frontStacks 9 Singlelist Definition 3.2.3.1 The definition of single list class from Project 1 is: template typename Type class Singlelist public: Singlelist(); Singlelist(); int size() const; bool empty() const; Type front() const; Type back() const; SinglenodeType head() const; SinglenodeType tail() const; int count( Type const ) const; void pushfront( Type const ); void pushback( Type const ); Type popfront(); int erase( Type const ); ;Stacks 10 StackasList Class 3.2.3.1 The stack class using a singly linked list has a single private member variable: template typename Type class Stack private: SinglelistType list; public: bool empty() const; Type top() const; void push( Type const ); Type pop(); ;Stacks 11 StackasList Class 3.2.3.1 A constructor and destructor is not needed – Because list is declared, the compiler will call the constructor of the Singlelist class when the Stack is constructed template typename Type class Stack private: SinglelistType list; public: bool empty() const; Type top() const; void push( Type const ); Type pop(); ;Stacks 12 StackasList Class 3.2.3.1 The empty and push functions just call the appropriate functions of the Singlelist class template typename Type bool StackType::empty() const return list.empty(); template typename Type void StackType::push( Type const obj ) list.pushfront( obj ); Stacks 13 StackasList Class 3.2.3.1 The top and pop functions, however, must check the boundary case: template typename Type Type StackType::top() const if ( empty() ) throw underflow(); template typename Type return list.front(); Type StackType::pop() if ( empty() ) throw underflow(); return list.popfront(); Stacks 14 Array Implementation 3.2.3.2 For oneended arrays, all operations at the back are Q(1) st th Front/1 Back/n Find Q(1)Q(1) Insert Q(n)Q(1) Erase Q(n)Q(1)Stacks 15 Destructor 3.2.3.2 We need to store an array: – In C++, this is done by storing the address of the first entry Type array; We need additional information, including: – The number of objects currently in the stack int stacksize; – The capacity of the array int arraycapacity;Stacks 16 StackasArray Class 3.2.3.2 We need to store an array: – In C++, this is done by storing the address of the first entry template typename Type class Stack private: int stacksize; int arraycapacity; Type array; public: Stack( int = 10 ); Stack(); bool empty() const; Type top() const; void push( Type const ); Type pop(); ;Stacks 17 Constructor 3.2.3.2 The class is only storing the address of the array – We must allocate memory for the array and initialize the member variables – The call to new Typearraycapacity makes a request to the operating system for arraycapacity objects include algorithm // ... template typename Type StackType::Stack( int n ): stacksize( 0 ), arraycapacity( std::max( 1, n ) ), array( new Typearraycapacity ) // Empty constructor Stacks 18 Constructor 3.2.3.2 Warning: in C++, the variables are initialized in the order in which they are defined: template typename Type class Stack private: template typename Type int stacksize; StackType::Stack( int n ): int arraycapacity; stacksize( 0 ), Type array; arraycapacity( std::max( 1, n ) ), public: array( new Typearraycapacity ) Stack( int = 10 ); Stack(); // Empty constructor bool empty() const; Type top() const; void push( Type const ); Type pop(); ;Stacks 19 Destructor 3.2.3.2 The call to new in the constructor requested memory from the operating system – The destructor must return that memory to the operating system: template typename Type StackType::Stack() delete array; Stacks 20 Empty 3.2.3.2 The stack is empty if the stack size is zero: template typename Type bool StackType::empty() const return ( stacksize == 0 ); The following is unnecessarily tedious: – The == operator evaluates to either true or false if ( stacksize == 0 ) return true; else return false; Stacks 21 Top 3.2.3.2 If there are n objects in the stack, the last is located at index n– 1 template typename Type Type StackType::top() const if ( empty() ) throw underflow(); return arraystacksize 1; Stacks 22 Pop 3.2.3.2 Removing an object simply involves reducing the size – It is invalid to assign the last entry to ―0‖ – By decreasing the size, the previous top of the stack is now at the location stacksize template typename Type Type StackType::pop() if ( empty() ) throw underflow(); stacksize; return arraystacksize; Stacks 23 Push 3.2.3.2 Pushing an object onto the stack can only be performed if the array is not full template typename Type void StackType::push( Type const obj ) if ( stacksize == arraycapacity ) throw overflow(); // Best solution arraystacksize = obj; ++stacksize; Stacks 24 Exceptions 3.2.3.2 The case where the array is full is not an exception defined in the Abstract Stack If the array is filled, we have five options: – Increase the size of the array – Throw an exception – Ignore the element being pushed – Replace the current top of the stack – Put the pushing process to ―sleep‖ until something else removes the top of the stack Include a member function bool full() const;Stacks 25 Array Capacity 3.2.4 If dynamic memory is available, the best option is to increase the array capacity If we increase the array capacity, the question is: – How much – By a constant arraycapacity += c; – By a multiple arraycapacity = c;Stacks 26 Array Capacity 3.2.4 First, let us visualize what must occur to allocate new memoryStacks 27 Array Capacity 3.2.4 First, this requires a call to new TypeN where N is the new capacity – We must have access to this so we must store the address returned by new in a local variable, say tmpStacks 28 Array Capacity 3.2.4 Next, the values must be copied overStacks 29 Array Capacity 3.2.4 The memory for the original array must be deallocated WStacks 30 Array Capacity 3.2.4 Finally, the appropriate member variables must be reassignedStacks 31 Array Capacity 3.2.4 The implementation: void doublecapacity() Type tmparray = new Type2arraycapacity; Stacks 32 Array Capacity 3.2.4 The implementation: void doublecapacity() Type tmparray = new Type2arraycapacity; tmparray Stacks 33 Array Capacity 3.2.4 The implementation: void doublecapacity() Type tmparray = new Type2arraycapacity; for ( int i = 0; i arraycapacity; ++i ) tmparray tmparrayi = arrayi; Stacks 34 Array Capacity 3.2.4 The implementation: void doublecapacity() Type tmparray = new Type2arraycapacity; for ( int i = 0; i arraycapacity; ++i ) tmparray tmparrayi = arrayi; W delete array; Stacks 35 Array Capacity 3.2.4 The implementation: void doublecapacity() Type tmparray = new Type2arraycapacity; for ( int i = 0; i arraycapacity; ++i ) tmparray tmparrayi = arrayi; delete array; array = tmparray; arraycapacity = 2; Stacks 36 Array Capacity 3.2.4 Back to the original question: – How much do we change the capacity – Add a constant – Multiply by a constant First, we recognize that any time that we push onto a full stack, this requires n copies and the run time is Q(n) Therefore, push is usually Q(1) except when new memory is requiredStacks 37 Array Capacity 3.2.4 To state the average run time, we will introduce the concept of amortized time: – If n operations requires Q(f(n)), we will say that an individual operation has an amortized run time of Q(f(n)/n) – Therefore, if inserting n objects requires: 2 •Q(n ) copies, the amortized time is Q(n) •Q(n) copies, the amortized time is Q(1) Stacks 38 Array Capacity 3.2.4 Let us consider the case of increasing the capacity by 1 each time the array is full – With each insertion when the array is full, this requires all entries to be copiedStacks 39 Array Capacity 3.2.4 Suppose we double the number of entries each time the array is full – Now the number of copies appears to be significantly fewerStacks 40 Array Capacity 3.2.4.1 Suppose we insert k objects th – The pushing of the k object on the stack requires k copies – The total number of copies is now given by: n n  n(n1) n(n1) 2  (k1) knnQn   2 2 k1 k1 – Therefore, the amortized number of copies 2 is given by n  QQn  n  – Therefore each push must run in Q(n) time – The wasted space, however is Q(1)Stacks 41 Array Capacity 3.2.4.2 Suppose we double the array size each time it is full: – We must make 1, 2, 4, 8, 16, 32, 64, 128, ... copies – Inserting n objects would therefore require 1, 2, 4, 8, ..., all the k k lg(n) way up to the largest 2 n or  lg(n)   lg(n)1 k   2 2 1  k0 lg(nn )1 lg( ) 1  21 2 21 2nn1Q  – Therefore the amortized number of copies per insertion is Q(1) – The wasted space, however is O(n)Stacks 42 Array Capacity 3.2.4.3 What if we increase the array size by a larger constant – For example, increase the array size by 4, 8, 100Stacks 43 Array Capacity 3.2.4.3 Here we view the number of copies required when increasing the array size by 4; however, in general, suppose we increase it by a constant value m n n  1  n /m n /m 2 n n m m  2 mkm kQn  2 2m 2 k1 k1 Therefore, the amortized run time per insertion is Q(n)Stacks 44 Array Capacity 3.2.4.3 Note the difference in worstcase amortized scenarios: Copies per Unused Insertion Memory Increase by 1 n– 10 Increase by m n/m m– 1 Increase by a factor of 2 1 n Increase by a factor of r 1 1/(r– 1) (r– 1)n The web site http://www.ece.uwaterloo.ca/ece250/Algorithms/Arrayresizing/ discusses the consequences of various values of rStacks 45 Application: Parsing 3.2.5 Most parsing uses stacks Examples includes: – Matching tags in XHTML – In C++, matching • parentheses ( ... ) • brackets, and ... • braces ... Stacks 46 Parsing XHTML 3.2.5.1 The first example will demonstrate parsing XHTML We will show how stacks may be used to parse an XHTML document You will use XHTML (and more generally XML and other markup languages) in the workplaceStacks 47 Parsing XHTML 3.2.5.1 A markup language is a means of annotating a document to given context to the text – The annotations give information about the structure or presentation of the text The best known example is HTML, or HyperText Markup Language – We will look at XHTMLStacks 48 Parsing XHTML 3.2.5.1 XHTML is made of nested – opening tags, e.g., someidentifier, and – matching closing tags, e.g., /someidentifier html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /htmlStacks 49 Parsing XHTML 3.2.5.1 Nesting indicates that any closing tag must match the most recent opening tag Strategy for parsing XHTML: – read though the XHTML linearly – place the opening tags in a stack – when a closing tag is encountered, check that it matches what is on top of the stack and Stacks 50 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html htmlStacks 51 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html headStacks 52 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html head titleStacks 53 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html head titleStacks 54 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html headStacks 55 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html bodyStacks 56 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html body pStacks 57 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html body p iStacks 58 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html body p iStacks 59 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html body pStacks 60 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html html bodyStacks 61 Parsing XHTML 3.2.5.1 html headtitleHello/title/head bodypThis appears in the ibrowser/i./p/body /html htmlStacks 62 Parsing XHTML 3.2.5.1 We are finished parsing, and the stack is empty Possible errors: – a closing tag which does not match the opening tag on top of the stack – a closing tag when the stack is empty – the stack is not empty at the end of the documentStacks 63 HTML 3.2.5.1 Old HTML required neither closing tags nor nesting html headtitleHello/title/head bodypThis is a list of topics: ol para ends with start of list liiveni implied /li lividi italics continues livici/i /ol endoffile implies /body/html Parsers were therefore specific to HTML – Results: ambiguities and inconsistenciesStacks 64 XML 3.2.5.1 XHTML is an implementation of XML XML defines a class of generalpurpose eXtensible Markup Languages designed for sharing information between systems The same rules apply for any flavour of XML: – opening and closing tags must match and be nestedStacks 65 Parsing C++ 3.2.5.2 The next example shows how stacks may be used in parsing C++ Those taking ECE 351 Compilers will use this For other students, it should help understand, in part: – how a compiler works, and – why programming languages have the structure they doStacks 66 Parsing C++ 3.2.5.2 Like opening and closing tags, C++ parentheses, brackets, and braces must be similarly nested: void initialize( int array, int n ) for ( int i = 0; i n; ++i ) arrayi = 0; http://xkcd.com/859/Stacks 67 Parsing C++ 3.2.5.2 For C++, the errors are similar to that for XHTML, however: – many XHTML parsers usually attempt to ―correct‖ errors (e.g., insert missing tags) – C++ compilers will simply issue a parse error: eceunix:1 cat example1.cpp include vector int main() std::vectorint v(100; return 0; eceunix:2 g++ example1.cpp example1.cpp: In function 'int main()': example1.cpp:3: error: expected ')' before '' tokenStacks 68 Parsing C++ 3.2.5.2 For C++, the errors are similar to that for XHTML, however: – many XHTML parsers usually attempt to ―correct‖ errors (e.g., insert missing tags) – C++ compilers will simply issue a parse error: eceunix:1 cat example2.cpp include vector int main() std::vectorint v(100); v0 = 3; return 0; eceunix:2 g++ example2.cpp example2.cpp: In function 'int main()': example2.cpp:4: error: expected ';' before '' tokenStacks 69 Function Calls 3.2.5.3 This next example discusses function calls In ECE 222 Digital Computers, you will see how stacks are implemented in hardware on all CPUs to facilitate function calling The simple features of a stack indicate why almost all programming languages are based on function callsStacks 70 Function Calls 3.2.5.3 Function calls are similar to problem solving presented earlier: – you write a function to solve a problem – the function may require subproblems to be solved, hence, it may call another function – once a function is finished, it returns to the function which called itStacks 71 Function Calls 3.2.5.3 You will notice that the when a function returns, execution and the return value is passed back to the last function which was called This is again, the lastin—firstout property – Covered in much greater detail in ECE 222 Today’s CPUs have hardware specifically designed to facilitate function callingStacks 72 ReversePolish Notation 3.2.5.4 Normally, mathematics is written using what we call infix notation: (3 + 4) × 5 – 6 The operator is placed between to operands One weakness: parentheses are required (3 + 4) × 5 – 6 = 29 3 + 4 × 5 – 6 = 17 3 + 4 × (5 – 6) = –1 (3 + 4) × (5 – 6) = –7Stacks 73 ReversePolish Notation 3.2.5.4 Alternatively, we can place the operands first, followed by the operator: (3 + 4) × 5 – 6 3 4 + 5 × 6 – Parsing reads lefttoright and performs any operation on the last two operands: 3 4 + 5 × 6 – 7 5 × 6 – 35 6 – 29Stacks 74 ReversePolish Notation 3.2.5.4 This is called reversePolish notation after the mathematician Jan Łukasiewicz – As you will see in ECE 222, this forms the basis of the recursive stack used on all processors He also made significant contributions to logic and other fields – Including humour… http://www.audiovis.nac.gov.pl/ http://xkcd.com/645/Stacks 75 ReversePolish Notation 3.2.5.4 Other examples: 3 4 5 × + 6 – 3 20 + 6 – 23 6 – 17 3 4 5 6 – × + 3 4 –1 × + 3–4 + –1Stacks 76 ReversePolish Notation 3.2.5.4 Benefits: – No ambiguity and no brackets are required – It is the same process used by a computer to perform computations: • operands must be loaded into registers before operations can be performed on them – ReversePolish can be processed using stacksStacks 77 ReversePolish Notation 3.2.5.4 ReversePolish notation is used with some programming languages – e.g., postscript, pdf, and HP calculators Similar to the thought process required for writing assembly language code – you cannot perform an operation until you have all of the operands loaded into registers MOVE.L 2A, D1 ; Load 42 into Register D1 MOVE.L 100, D2 ; Load 256 into Register D2 ADD D2, D1 ; Add D2 into D1Stacks 78 ReversePolish Notation 3.2.5.4 A quick example of postscript: 0 10 360 Go from 0 to 360 degrees in 10degree steps newpath Start a new path gsave Keep rotations temporary 144 144 moveto rotate Rotate by degrees on stack from 'for' 72 0 rlineto stroke grestore Get back the unrotated state for Iterate over angles http://www.tailrecursive.org/postscript/examples/rotate.htmlStacks 79 ReversePolish Notation 3.2.5.4 The easiest way to parse reversePolish notation is to use an operand stack: – operands are processed by pushing them onto the stack – when processing an operator: • pop the last two items off the operand stack, • perform the operation, and • push the result back onto the stackStacks 80 ReversePolish Notation 3.2.5.4 Evaluate the following reversePolish expression using a stack: 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × +Stacks 81 ReversePolish Notation 3.2.5.4 Push 1 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 1Stacks 82 ReversePolish Notation 3.2.5.4 Push 1 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 2 1Stacks 83 ReversePolish Notation 3.2.5.4 Push 3 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 3 2 1Stacks 84 ReversePolish Notation 3.2.5.4 Pop 3 and 2 and push 2 + 3 = 5 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 5 1Stacks 85 ReversePolish Notation 3.2.5.4 Push 4 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 4 5 1Stacks 86 ReversePolish Notation 3.2.5.4 Push 5 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 5 4 5 1Stacks 87 ReversePolish Notation 3.2.5.4 Push 6 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 6 5 4 5 1Stacks 88 ReversePolish Notation 3.2.5.4 Pop 6 and 5 and push 5 × 6 = 30 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 30 4 5 1Stacks 89 ReversePolish Notation 3.2.5.4 Pop 30 and 4 and push 4 – 30 = –26 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + –26 5 1Stacks 90 ReversePolish Notation 3.2.5.4 Push 7 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 7 –26 5 1Stacks 91 ReversePolish Notation 3.2.5.4 Pop 7 and –26 and push –26 × 7 = –182 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + –182 5 1Stacks 92 ReversePolish Notation 3.2.5.4 Pop –182 and 5 and push –182 + 5 = –177 1 2 3 + 4 5 6 ×– 7 × +– 8 9 × + –177 1Stacks 93 ReversePolish Notation 3.2.5.4 Pop –177 and 1 and push 1 – (–177) = 178 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 178Stacks 94 ReversePolish Notation 3.2.5.4 Push 8 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 8 178Stacks 95 ReversePolish Notation 3.2.5.4 Push 1 onto the stack 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 9 8 178Stacks 96 ReversePolish Notation 3.2.5.4 Pop 9 and 8 and push 8 × 9 = 72 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 72 178Stacks 97 ReversePolish Notation 3.2.5.4 Pop 72 and 178 and push 178 + 72 = 250 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + 250Stacks 98 ReversePolish Notation 3.2.5.4 Thus 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × + evaluates to the value on the top: 250 The equivalent infix notation is ((1 – ((2 + 3) + ((4 – (5 × 6)) × 7))) + (8 × 9)) We reduce the parentheses using orderofoperations: 1 – (2 + 3 + (4 – 5 × 6) × 7) + 8 × 9Stacks 99 ReversePolish Notation 3.2.5.4 Incidentally, 1 – 2 + 3 + 4 – 5 × 6 × 7 + 8 × 9 = – 132 which has the reversePolish notation of 1 2 – 3 + 4 + 5 6 7 ××– 8 9 × + For comparison, the calculated expression was 1 2 3 + 4 5 6 ×– 7 × + – 8 9 × +Stacks 100 Standard Template Library 3.2.5.5 The Standard Template Library (STL) has a wrapper class stack with the following declaration: template typename T class stack public: stack(); // not quite true... bool empty() const; int size() const; const T top() const; void push( const T ); void pop(); ;Stacks 101 Standard Template Library 3.2.6 include iostream include stack using namespace std; int main() stackint istack; istack.push( 13 ); istack.push( 42 ); cout "Top: " istack.top() endl; istack.pop(); // no return value cout "Top: " istack.top() endl; cout "Size: " istack.size() endl; return 0; Stacks 102 Standard Template Library 3.2.6 The reason that the stack class is termed a wrapper is because it uses a different container class to actually store the elements The stack class simply presents the stack interface with appropriately named member functions: – push, pop , and topStacks 103 Stacks The stack is the simplest of all ADTs – Understanding how a stack works is trivial The application of a stack, however, is not in the implementation, but rather: – Where possible, create a design which allows the use of a stack We looked at: – Parsing, function calls, and reverse PolishStacks 104 References rd Donald E. Knuth, The Art of Computer Programming, Volume 1: Fundamental Algorithms, 3 Ed., Addison Wesley, 1997, §2.2.1, p.238. Cormen, Leiserson, and Rivest, Introduction to Algorithms, McGraw Hill, 1990, §11.1, p.200. rd Weiss, Data Structures and Algorithm Analysis in C++, 3 Ed., Addison Wesley, §3.6, p.94. Koffman and Wolfgang, ―Objects, Abstraction, Data Strucutes and Design using C++‖, John Wiley Sons, Inc., Ch. 5. Wikipedia, http://en.wikipedia.org/wiki/Stack(abstractdatatype) These slides are provided for the ECE 250 Algorithms and Data Structures course. The material in it reflects Douglas W. Harder’s best judgment in light of the information available to him at the time of preparation. Any reliance on these course slides by any party for any other purpose are the responsibility of such parties. Douglas W. Harder accepts no responsibility for damages, if any, suffered by any party as a result of decisions made or actions based on these course slides for any other purpose than that for which it was intended.
Website URL
Comment
sharer
Presentations
Free
Document Information
Category:
Presentations
User Name:
Dr.SethPatton
User Type:
Teacher
Country:
United Kingdom
Uploaded Date:
22-07-2017