Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 64 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
64
Dung lượng
5,26 MB
Nội dung
Algorithms R OBERT S EDGEWICK | K EVIN W AYNE 1.3 B AGS, QUEUES, AND S TACKS ‣ stacks ‣ resizing arrays Algorithms F O U R T H E D I T I O N R OBERT S EDGEWICK | K EVIN W AYNE http://algs4.cs.princeton.edu ‣ queues ‣ generics ‣ iterators ‣ applications Stacks and queues Fundamental data types Value: collection of objects Operations: insert, remove, iterate, test if empty Intent is clear when we insert Which item we remove? stack push pop queue enqueue dequeue Stack Examine the item most recently added LIFO = "last in first out" Queue Examine the item least recently added FIFO = "first in first out" Client, implementation, interface Separate interface and implementation Ex: stack, queue, bag, priority queue, symbol table, union-find, … Benefits Client can't know details of implementation ⇒ client has many implementation from which to choose Implementation can't know details of client needs ⇒ many clients can re-use the same implementation Design: creates modular, reusable libraries Performance: use optimized implementation where it matters Client: program using operations defined in interface Implementation: actual code implementing operations Interface: description of data type, basic operations 1.3 B AGS, QUEUES, AND S TACKS ‣ stacks ‣ resizing arrays Algorithms R OBERT S EDGEWICK | K EVIN W AYNE http://algs4.cs.princeton.edu ‣ queues ‣ generics ‣ iterators ‣ applications Stack API Warmup API Stack of strings data type push pop public class StackOfStrings StackOfStrings() void push(String item) String pop() boolean isEmpty() int size() create an empty stack insert a new string onto stack remove and return the string most recently added is the stack empty? number of strings on the stack Warmup client Reverse sequence of strings from standard input Stack test client Read strings from standard input If string equals "-", pop string from stack and print Otherwise, push string onto stack push pop public static void main(String[] args) { StackOfStrings stack = new StackOfStrings(); while (!StdIn.isEmpty()) { String s = StdIn.readString(); if (s.equals("-")) StdOut.print(stack.pop()); else stack.push(s); } } % more tobe.txt to be or not to - be - - that - - - is % java StackOfStrings < tobe.txt to be not that or be Stack: linked-list representation Maintain pointer to first node in a linked list; insert/remove from front StdIn StdOut to null to be be insert at front of linked list first or or not not to to - remove from front of linked list to - - that not be be be not to null not be or not or not or to null be or be or be to null be to null to null be to null to null or be that or to null be to null Stack pop: linked-list implementation save item to return String item = first.item; delete first node inner class private class Node { String item; Node next; } first = first.next; first or be to null first or be to null return saved item return item; Removing the first node in a linked list Stack push: linked-list implementation save a link to the list Node oldfirst = first; oldfirst first inner class private class Node { String item; Node next; } or be to null create a new node for the beginning first = new Node(); oldfirst first or be to null set the instance variables in the new node first.item = "not"; first.next = oldfirst; first not or be to null Inserting a new node at the beginning of a linked list Stack: linked-list implementation in Java public class LinkedStackOfStrings { private Node first = null; private class Node { String item; Node next; } public boolean isEmpty() { return first == null; private inner class (access modifiers don't matter) } public void push(String item) { Node oldfirst = first; first = new Node(); first.item = item; first.next = oldfirst; } public String pop() { String item = first.item; first = first.next; return item; } } 10 Bag API Main application Adding items to a collection and iterating (when order doesn't matter) a bag of marbles public class Bag implements Iterable Bag() create an empty bag void add(Item x) insert a new item onto bag int size() Iterable iterator() number of items in bag add( ) add( ) iterator for all items in bag for (Marble m : bag) process each marble m (in any order) Implementation Stack (without pop) or queue (without dequeue) 50 1.3 B AGS, QUEUES, AND S TACKS ‣ stacks ‣ resizing arrays Algorithms R OBERT S EDGEWICK | K EVIN W AYNE http://algs4.cs.princeton.edu ‣ queues ‣ generics ‣ iterators ‣ applications 1.3 B AGS, QUEUES, AND S TACKS ‣ stacks ‣ resizing arrays Algorithms R OBERT S EDGEWICK | K EVIN W AYNE http://algs4.cs.princeton.edu ‣ queues ‣ generics ‣ iterators ‣ applications Java collections library List interface java.util.List is API for an sequence of items public interface List implements Iterable List() boolean isEmpty() int size() create an empty list is the list empty? number of items void add(Item item) append item to the end Item get(int index) return item at given index Item remove(int index) boolean contains(Item item) Iteartor iterator() return and delete item at given index does the list contain the given item? iterator over all items in the list Implementations java.util.ArrayList uses resizing array; java.util.LinkedList uses linked list 53 Java collections library java.util.Stack Supports push(), pop(), and and iteration Also implements java.util.List interface from previous slide, including, get(), remove(), and contains() Bloated and poorly-designed API (why?) java.util.Queue An interface, not an implementation of a queue Best practices Use our implementations of Stack, Queue, and Bag 54 War story (from COS 226) Generate random open sites in an N-by-N percolation system percolates Jenny: pick (i, j) at random; if already open, repeat blocked does not percolate site Takes ~ c1 N seconds Kenny: create a java.util.ArrayList of N closed sites Pick an index at random and delete open Takes ~ c2 N seconds site open site connected to top no open site connected to Why is my program so slow? Kenny Lesson Don't use a library until you understand its API! This course Can't use a library until we've implemented it in class 55 Stack applications Parsing in a compiler Java virtual machine Undo in a word processor Back button in a Web browser PostScript language for printers Implementing function calls in a compiler 56 Function calls How a compiler implements a function Function call: push local environment and return address Return: pop return address and local environment Recursive function Function that calls itself Note Can always use an explicit stack to remove recursion gcd (216, 192) static int gcd(int p, int q) { if (q == 0) return p; else return gcd(q,gcd p %(192, q); 24) } static int gcd(int p, int q) { p = 192, q = 24 if (q == 0) return p; gcd else return gcd(q, p % (24, q); 0) } static int gcd(int p, int q) { if (q == 0) return p; p = 24, q = else return gcd(q, p % q); } p = 216, q = 192 57 it is easy to convince yourself that it computes the proper value: any time the algorithm encounters a subexpression consisting of two operands separated by an opArithmetic expressionerator, evaluation all surrounded by parentheses, it leaves the result of performing that operation on those operands on the operand stack The result is the same as if that value had appeared in the input instead of the subexpression, so we can think of replacing valuethe stack Goal Evaluate infix expressions (1+((2+3)*(4*5))) subexpression by the value to get an expression operator stack that would yield the same result We can apply +((2+3)*(4*5))) this argument again and again until we get a ( + ( ( + ) * ( single * ) )For)example, the algorithm comvalue ((2+3)*(4*5))) putes the same value of all of these expres+ sions: operand operator ( ( ( ( 101 + + + + ( ( ( ( 100 + ) * ( * ) ) ) * ( * ) ) ) * 20 ) ) ) Two-stack algorithm [E W Dijkstra] + +3)*(4*5))) + + 3)*(4*5))) + + )*(4*5))) (PROGRAM 4.3.5) is an implemen1 Value: push onto the stack.This code is a simple tationvalue of this method *(4*5))) + example of an interpreter : a program that in1 Operator: push onto the stack.by a given terprets theoperator computation specified (4*5))) + * string and performs the computation to ar1 Left parenthesis: ignore rive at the result A compiler is a program that *5))) + * converts the string into code on a lower-level Right parenthesis: machine pop operator and two values; that can the job This conversion 5))) + * * is a more complicated process than the steppush the result of applying that operator 5 by-step conversion used by an interpreter, but ))) + * * it is based the same underlying to those values onto the on operand stack.mechanism 20 Initially, Java was based on using an interpret)) + * er Now, however, the Java system includes a 100 compiler that converts arithmetic expressions ) + (and, more generally, Java programs) into code 101 for the Java virtual machine, an imaginary maContext An interpreter! chine that is easy to simulate on an actual computer Trace of expression evaluation (Program 4.3.5) Evaluate 58 Dijkstra's two-stack algorithm demo value stack infix expression operator stack (fully parenthesized) ( + ( ( + operand ) * ( * ) ) ) operator 59 Arithmetic expression evaluation public class Evaluate { public static void main(String[] args) { Stack ops = new Stack(); Stack vals = new Stack(); while (!StdIn.isEmpty()) { String s = StdIn.readString(); if (s.equals("(")) ; else if (s.equals("+")) ops.push(s); else if (s.equals("*")) ops.push(s); else if (s.equals(")")) { String op = ops.pop(); if (op.equals("+")) vals.push(vals.pop() + vals.pop()); else if (op.equals("*")) vals.push(vals.pop() * vals.pop()); } else vals.push(Double.parseDouble(s)); } StdOut.println(vals.pop()); } % java Evaluate } ( + ( ( + ) * ( * ) ) ) 101.0 60 Correctness Q Why correct? A When algorithm encounters an operator surrounded by two values within parentheses, it leaves the result on the value stack ( + ( ( + ) * ( * ) ) ) as if the original input were: ( + ( * ( * ) ) ) Repeating the argument: ( + ( * 20 ) ) ( + 100 ) 101 Extensions More ops, precedence order, associativity 61 Stack-based programming languages Observation Dijkstra's two-stack algorithm computes the same value if the operator occurs after the two values ( ( ( + ) ( * ) * ) + ) Observation All of the parentheses are redundant! + * * + Jan Lukasiewicz Bottom line Postfix or "reverse Polish" notation Applications Postscript, Forth, calculators, Java virtual machine, … 62 1.3 B AGS, QUEUES, AND S TACKS ‣ stacks ‣ resizing arrays Algorithms R OBERT S EDGEWICK | K EVIN W AYNE http://algs4.cs.princeton.edu ‣ queues ‣ generics ‣ iterators ‣ applications Algorithms R OBERT S EDGEWICK | K EVIN W AYNE 1.3 B AGS, QUEUES, AND S TACKS ‣ stacks ‣ resizing arrays Algorithms F O U R T H E D I T I O N R OBERT S EDGEWICK | K EVIN W AYNE http://algs4.cs.princeton.edu ‣ queues ‣ generics ‣ iterators ‣ applications