Java Course Notes CS3114_09212011

download Java Course Notes CS3114_09212011

of 344

description

Java Course Notes Complete Java course notes for a quick java review.

Transcript of Java Course Notes CS3114_09212011

  • Coursenotes

    CS3114: Data Structures andAlgorithms

    Clifford A. ShafferDepartment of Computer ScienceVirginia TechCopyright 2008-2011

  • Goals of this CourseReinforce the concept that costs and benefits exist for every data structure.

    Learn the commonly used data structures.These form a programmer's basic data structure ``toolkit.'

    Understand how to measure the cost of a data structure or program.These techniques also allow you to judge the merits of new data structures that you or others might invent.

  • Role in the CurriculumThis course represents a transition between learning to program courses (CS 1114, CS 2114) and content courses.To do well, you must be able to handle bothProgramming (we focus on projects with dynamic memory allocation and file processing)Content, theory and analysis*

  • The Need for Data StructuresData structures organize data more efficient programs.More powerful computers more complex applications.More complex applications demand more calculations.Complex computing tasks are unlike our everyday experience.

  • EfficiencyChoice of data structure or algorithm can make the difference between a program running in a few seconds or many days.A solution is said to be efficient if it solves the problem within its resource constraints.SpaceTimeThe cost of a solution is the amount of resources that the solution consumes.

  • Selecting a Data StructureSelect a data structure as follows:Analyze the problem to determine the basic operations that must be supported.Quantify the resource constraints for each operation.Select the data structure that best meets these requirements.

  • Costs and BenefitsEach data structure has costs and benefits.Rarely is one data structure better than another in all situations.Any data structure requires:space for each data item it stores,time to perform each basic operation,programming effort.

  • Costs and Benefits (cont)Each problem has constraints on available space and time.Only after a careful analysis of problem characteristics can we know the best data structure for the task.Bank example:Start account: a few minutesTransactions: a few secondsClose account: overnight

  • Some Questions to AskAre all data inserted into the data structure at the beginning, or are insertions interspersed with other operations?Can data be deleted?Are all data processed in some well-defined order, or is random access allowed?

  • Abstract Data TypesAbstract Data Type (ADT): a definition for a data type solely in terms of a set of values and a set of operations on that data type.

    Each ADT operation is defined by its inputs and outputs.

    Encapsulation: Hide implementation details.

  • Data StructureA data structure is the physical implementation of an ADT.Each operation associated with the ADT is implemented by one or more subroutines in the implementation.

    Data structure usually refers to an organization for data in main memory.

    File structure: an organization for data on peripheral storage, such as a disk drive.

  • MetaphorsAn ADT manages complexity through abstraction: metaphor.Hierarchies of labels

    Ex: transistors gates CPU.

    In a program, implement an ADT, then think only about the ADT, not its implementation.

  • Logical vs. Physical FormData items have both a logical and a physical form.

    Logical form: definition of the data item within an ADT.Ex: Integers in mathematical sense: +, -

    Physical form: implementation of the data item within a data structure.Ex: 16/32 bit integers, overflow.

  • Data TypeADT:TypeOperationsData Items: Logical FormData Items: Physical FormData Structure:Storage SpaceSubroutines

  • Example 1.8A typical database-style project will have many interacting parts.

  • SchedulingManaging large-scale projects involves scheduling activitiesIt is human nature to work better toward intermediate milestones.The same concepts can/should be applied to mid-sized projects encountered in class.For any project that needs more than a week of active work to complete, break into parts and design a schedule with milestones and deliverables.

  • Real Results #1CS2606, Fall 20063-4 week projectsKept schedule information:Estimated time requiredMilestones, estimated times for eachWeekly estimates of time spent.

  • Real Results #2Amount Done 1 Week Prior to Due Date

  • Real Results #3Results were significant:90% of scores below median were students who did less than 50% of the project prior to the last week.Few did poorly who put in > 50% time earlySome did well who didnt put in >50% time early, but most who did well put in the early time

  • Real Results #4Correlations:Strong correlation between early time and high scoreNo correlation between time spent and scoreNo correlation between % early time and total time

    *

  • What is the Mechanism?Correlations are not causalDo they behave that way because they are good, or does behaving that way make them good?Spreading projects over time allows the sleep on it heuristic to operateAvoiding the zombie effect makes people more productive (and cuts time requirements)

  • *Mathematical BackgroundSet concepts and notationLogarithmsRecursionInduction ProofsSummationsRecurrence Relations

  • Set

  • RelationsA relation R over a set S is a set of ordered pairs from S. Example: < > = Common Properties:

    Partial and total order relations

  • LogarithmDefinition:

  • Summation

  • RecursionAn algorithm is recursive if it calls itself to do part of its work.

    Example: 1. Compute n!2. Hanoi puzzle

  • Mathematical ProofThree templates for mathematical proofDirect ProofProof by ContradictionProof by mathematical induction

  • *Estimation TechniquesKnown as back of the envelope or back of the napkin calculationDetermine the major parameters that effect the problem.Derive an equation that relates the parameters to the problem.Select values for the parameters, and apply the equation to yield and estimated solution.

  • *Estimation ExampleHow many library bookcases does it take to store books totaling one million pages?

    Estimate:Pages/inchFeet/shelfShelves/bookcase

  • *Algorithm EfficiencyThere are often many approaches (algorithms) to solve a problem. How do we choose between them?

    At the heart of computer program design are two (sometimes conflicting) goals.To design an algorithm that is easy to understand, code, debug.To design an algorithm that makes efficient use of the computers resources.

  • *Algorithm Efficiency (cont)Goal (1) is the concern of Software Engineering.

    Goal (2) is the concern of data structures and algorithm analysis.

    When goal (2) is important, how do we measure an algorithms cost?

  • *How to Measure Efficiency?Empirical comparison (run programs)Asymptotic Algorithm Analysis

    Critical resources:

    Factors affecting running time:

    For most algorithms, running time depends on size of the input.

    Running time is expressed as T(n) for some function T on input size n.

  • *Examples of Growth RateExample 1.

    /** @return Position of largest value in "A */static int largest(int[] A) { int currlarge = 0; // Position of largest for (int i=1; i

  • *Examples (cont)Example 2: Assignment statement.

    Example 3:

    sum = 0;for (i=1; i

  • *Growth Rate Graph

  • *Best, Worst, Average CasesNot all inputs of a given size take the same time to run.

    Sequential search for K in an array of n integers:Begin at first element in array and look at each element in turn until K is found

    Best case:

    Worst case:

    Average case:

  • *Which Analysis to Use?While average time appears to be the fairest measure, it may be difficult to determine.

    When is the worst case time important?

  • *Faster Computer or Algorithm?Suppose we buy a computer 10 times faster.n: size of input that can be processed in one second on old computer (in 1000 computational units)n: size of input that can be processed in one second on new computer (in 10,000 computational units)

    T(n)nnChangen/n10n1001,000n = 10n1010n21031.6n= 10n3.1610n34n = n + 11 + 1/n

  • *Asymptotic Analysis: Big-ohDefinition: For T(n) a non-negatively valued function, T(n) is in the set O(f(n)) if there exist two positive constants c and n0 such that T(n) n0.

    Use: The algorithm is in O(n2) in [best, average, worst] case.

    Meaning: For all data sets big enough (i.e., n>n0), the algorithm always executes in less than cf(n) steps in [best, average, worst] case.

  • *Big-oh Notation (cont)Big-oh notation indicates an upper bound.

    Example: If T(n) = 3n2 then T(n) is in O(n2).

    Look for the tightest upper bound:While T(n) = 3n2 is in O(n3), we prefer O(n2).

  • *Big-Oh ExamplesExample 1: Finding value X in an array (average cost).Then T(n) = csn/2.For all values of n > 1, csn/2
  • *Big-Oh Examples (2)Example 2: Suppose T(n) = c1n2 + c2n, where c1 and c2 are positive.c1n2 + c2n
  • *A Common MisunderstandingThe best case for my algorithm is n=1 because that is the fastest. WRONG!Big-oh refers to a growth rate as n grows to .Best case is defined for the input of size n that is cheapest among all inputs of size n.

  • *Big-OmegaDefinition: For T(n) a non-negatively valued function, T(n) is in the set (g(n)) if there exist two positive constants c and n0 such that T(n) >= cg(n) for all n > n0.

    Meaning: For all data sets big enough (i.e., n > n0), the algorithm always requires more than cg(n) steps.

    Lower bound.

  • *Big-Omega ExampleT(n) = c1n2 + c2n.c1n2 + c2n >= c1n2 for all n > 1.T(n) >= cn2 for c = c1 and n0 = 1.Therefore, T(n) is in (n2) by the definition.We want the greatest lower bound.

  • *Theta NotationWhen big-Oh and coincide, we indicate this by using (big-Theta) notation.

    Definition: An algorithm is said to be in (h(n)) if it is in O(h(n)) and it is in (h(n)).

  • *A Common MisunderstandingConfusing worst case with upper bound.

    Upper bound refers to a growth rate.

    Worst case refers to the worst input from among the choices for possible inputs of a given size.

  • *Simplifying RulesIf f(n) is in O(g(n)) and g(n) is in O(h(n)), then f(n) is in O(h(n)).If f(n) is in O(kg(n)) for some constant k > 0, then f(n) is in O(g(n)).If f1(n) is in O(g1(n)) and f2(n) is in O(g2(n)), then (f1 + f2)(n) is in O(max(g1(n), g2(n))).If f1(n) is in O(g1(n)) and f2(n) is in O(g2(n)) then f1(n)f2(n) is in O(g1(n)g2(n)).

  • *Time Complexity Examples (1)Example 3.9: a = b;

    This assignment takes constant time, so it is (1).

    Example 3.10:

    sum = 0;for (i=1; i

  • *Time Complexity Examples (2)Example 3.11:

    sum = 0;for (j=1; j

  • *Time Complexity Examples (3)Example 3.12:

    sum1 = 0;for (i=1; i

  • *Time Complexity Examples (4)Example 3.13:

    sum1 = 0;for (k=1; k

  • *Binary Search

    How many elements are examined in worst case?

  • *Binary Search/** @return The position of an element in sorted array A with value k. If k is not in A,return A.length. */static int binary(int[] A, int k) { int l = -1; // Set l and r int r = A.length; // beyond array bounds while (l+1 != r) { // Stop when l, r meet int i = (l+r)/2; // Check middle if (k < A[i]) r = i; // In left half if (k == A[i]) return i; // Found it if (k > A[i]) l = i; // In right half } return A.length; // Search value not in A}

  • *Other Control Statementswhile loop: Analyze like a for loop.

    if statement: Take greater complexity of then/else clauses.

    switch statement: Take complexity of most expensive case.

    Subroutine call: Complexity of the subroutine.

  • *ProblemsProblem: a task to be performed.Best thought of as inputs and matching outputs.Problem definition should include constraints on the resources that may be consumed by any acceptable solution.

  • *Problems (cont)Problems mathematical functionsA function is a matching between inputs (the domain) and outputs (the range).An input to a function may be single number, or a collection of information.The values making up an input are called the parameters of the function.A particular input must always result in the same output every time the function is computed.

  • *Algorithms and ProgramsAlgorithm: a method or a process followed to solve a problem.A recipe.

    An algorithm takes the input to a problem (function) and transforms it to the output.A mapping of input to output.

    A problem can have many algorithms.

  • *Analyzing ProblemsUpper bound: Upper bound of best known algorithm.

    Lower bound: Lower bound for every possible algorithm.

  • *Analyzing Problems: ExampleMay or may not be able to obtain matching upper and lower bounds.

    Example of imperfect knowledge: Sorting

    1. Cost of I/O: (n).2. Bubble or insertion sort: O(n2).3. A better sort (Quicksort, Mergesort, Heapsort, etc.): O(n log n).4. We prove later that sorting is in (n log n).

  • *Space/Time Tradeoff PrincipleOne can often reduce time if one is willing to sacrifice space, or vice versa.Encoding or packing informationBoolean flagsTable lookupFactorials

    Disk-based Space/Time Tradeoff Principle: The smaller you make the disk storage requirements, the faster your program will run.

  • *Multiple ParametersCompute the rank ordering for all C pixel values in a picture of P pixels.

    for (i=0; i

  • *Space ComplexitySpace complexity can also be analyzed with asymptotic complexity analysis.

    Time: AlgorithmSpace: Data Structure

  • *ListsA list is a finite, ordered sequence of data items.

    Important concept: List elements have a position.

    Notation:

    What operations should we implement?

  • *List Implementation ConceptsOur list implementation will support the concept of a current position.

    Operations will act relative to the current position.

  • *List ADTpublic interface List { public void clear(); public void insert(E item); public void append(E item); public E remove(); public void moveToStart(); public void moveToEnd(); public void prev(); public void next(); public int length(); public int currPos(); public void moveToPos(int pos); public E getValue();}

  • *List ADT ExamplesList:

    L.insert(99);

    Result:

    Iterate through the whole list:

    for (L.moveToStart(); L.currPos()

  • *List Find Function/** @return True if k is in list L, false otherwise */public static booleanfind(List L, int k) { for (L.moveToStart(); L.currPos()
  • *Array-Based List Insert

  • *Array-Based List Class (1)class AList implements List { private static final int defaultSize = 10;

    private int maxSize; private int listSize; private int curr; private E[] listArray;

    // Constructors AList() { this(defaultSize); } @SuppressWarnings("unchecked") AList(int size) { maxSize = size; listSize = curr = 0; listArray = (E[])new Object[size]; }

  • *Array-Based List Class (2)public void clear() { listSize = curr = 0; }public void moveToStart() { curr = 0; }public void moveToEnd() { curr = listSize; }public void prev() { if (curr != 0) curr--; }public void next() { if (curr < listSize) curr++; }public int length() { return listSize; }public int currPos() { return curr; }

  • *Array-Based List Class (3)public void moveToPos(int pos) { assert (pos>=0) && (pos= 0) && (curr < listSize) : "No current element"; return listArray[curr];}

  • *Insert/** Insert "it" at current position */public void insert(E it) { assert listSize < maxSize : "List capacity exceeded"; for (int i=listSize; i>curr; i--) listArray[i] = listArray[i-1]; listArray[curr] = it; listSize++;}

  • *Appendpublic void append(E it) { // Append "it" assert listSize < maxSize : "List capacity exceeded"; listArray[listSize++] = it;}

  • *Remove/** Remove and return the current element */public E remove() { if ((curr < 0) || (curr >= listSize)) return null; E it = listArray[curr]; for(int i=curr; i
  • Linked List ManipulationIf you would like practice with linked lists, check out JHAVEPOP:http://jhave.org/jhavepop/(AlgoViz Catalog entry http://algoviz.org/catalog/entry/1935)

    *

  • *Link ClassDynamic allocation of new list elements.class Link { private E element; private Link next;

    // Constructors Link(E it, Link nextval) { element = it; next = nextval; } Link(Link nextval) { next = nextval; }

    Link next() { return next; } Link setNext(Link nextval) { return next = nextval; } E element() { return element; } E setElement(E it) { return element = it; }}

  • *Linked List Position (1)

  • *Linked List Position (2)

  • *Linked List Class (1)class LList implements List { private Link head; private Link tail; protected Link curr; int cnt;

    //Constructors LList(int size) { this(); } LList() { curr = tail = head = new Link(null); cnt = 0; }

  • *Linked List Class (2)public void clear() { head.setNext(null); curr = tail = head = new Link(null); cnt = 0;}public void moveToStart() { curr = head; }public void moveToEnd() { curr = tail; }public int length() { return cnt; }public void next() { if (curr != tail) { curr = curr.next(); }}public E getValue() { assert curr.next() != null : "Nothing to get"; return curr.next().element();}

  • *Insertion

  • *Insert/Append// Insert "it" at current positionpublic void insert(E it) { curr.setNext(new Link(it, curr.next())); if (tail == curr) tail = curr.next(); cnt++;}

    public void append(E it) { tail = tail.setNext(new Link(it, null)); cnt++;}

  • *Removal

  • *Remove/** Remove and return current element */public E remove() { if (curr.next() == null) return null; E it = curr.next().element(); if (tail == curr.next()) tail = curr; curr.setNext(curr.next().next()); cnt--; return it; }

  • *Prev/** Move curr one step left; no change if already at front */public void prev() { if (curr == head) return; Link temp = head; // March down list until we find the // previous element while (temp.next() != curr) temp = temp.next(); curr = temp;}

  • *Get/Set Position/** Return position of the current element */public int currPos() { Link temp = head; int i; for (i=0; curr != temp; i++) temp = temp.next(); return i;}

    /** Move down list to "pos" position */public void moveToPos(int pos) { assert (pos>=0) && (pos

  • *Comparison of ImplementationsArray-Based Lists:Insertion and deletion are (n).Prev and direct access are (1).Array must be allocated in advance.No overhead if all array positions are full.

    Linked Lists:Insertion and deletion are (1).Prev and direct access are (n).Space grows with number of elements.Every element requires overhead.

  • *Space ComparisonBreak-even point:

    DE = n(P + E);

    n = DE P + E

    E: Space for data value.P: Space for pointer.D: Number of elements in array.

  • Space ExampleArray-based list: Overhead is one pointer (4 bytes) per position in array whether used or not.Linked list: Overhead is two pointers per link nodeone to the element, one to the next linkData is the same for both.When is the space the same?When the array is half full*

  • *FreelistsSystem new and garbage collection are slow.Add freelist support to the Link class.

  • Link Class Extensionsstatic Link freelist = null;

    static Link get(E it, Link nextval) { if (freelist == null) return new Link(it, nextval); Link temp = freelist; freelist = freelist.next(); temp.setElement(it); temp.setNext(nextval); return temp;}

    void release() { // Return to freelist element = null; next = freelist; freelist = this;}

    *

  • *Using Freelistpublic void insert(E it) { curr.setNext(Link.get(it, curr.next())); if (tail == curr) tail = curr.next(); cnt++;}

    public E remove() { if (curr.next() == null) return null; E it = curr.next().element(); if (tail == curr.next()) tail = curr; Link tempptr = curr.next(); curr.setNext(curr.next().next()); tempptr.release(); cnt--; return it; }

  • *Doubly Linked Listsclass DLink { private E element; private DLink next; private DLink prev;

    DLink(E it, DLink p, DLink n) { element = it; prev = p; next = n; } DLink(DLink p, DLink n) { prev = p; next = n; }

    DLink next() { return next; } DLink setNext(DLink nextval) { return next = nextval; } DLink prev() { return prev; } DLink setPrev(DLink prevval) { return prev = prevval; } E element() { return element; } E setElement(E it) { return element = it; }}

  • *Doubly Linked Lists

  • *Doubly Linked Insert

  • *Doubly Linked Insertpublic void insert(E it) { curr.setNext( new DLink(it, curr, curr.next())); curr.next().next().setPrev(curr.next()); cnt++;}

  • *Doubly Linked Remove

  • *Doubly Linked Removepublic E remove() { if (curr.next() == tail) return null; E it = curr.next().element(); curr.next().next().setPrev(curr); curr.setNext(curr.next().next()); cnt--; return it; }

  • *StacksLIFO: Last In, First Out.

    Restricted form of list: Insert and remove only at front of list.

    Notation:Insert: PUSHRemove: POPThe accessible element is called TOP.

  • *Stack ADTpublic interface Stack { /** Reinitialize the stack. */ public void clear();

    /** Push an element onto the top of the stack. @param it Element being pushed onto the stack.*/ public void push(E it);

    /** Remove and return top element. @return The element at the top of the stack.*/ public E pop();

    /** @return A copy of the top element. */ public E topValue();

    /** @return Number of elements in the stack. */ public int length();};

  • *Array-Based Stack// Array-based stack implementationprivate int maxSize; // Max size of stackprivate int top; // Index for topprivate E [] listArray;

    Issues:Which end is the top?Where does top point to?What are the costs of the operations?

  • *Linked Stackclass LStack implements Stack { private Link top; private int size;

    What are the costs of the operations?

    How do space requirements compare to the array-based stack implementation?

  • *QueuesFIFO: First in, First Out

    Restricted form of list: Insert at one end, remove from the other.

    Notation:Insert: EnqueueDelete: DequeueFirst element: FrontLast element: Rear

  • *Queue Implementation (1)

  • *Queue Implementation (2)

  • *DictionaryOften want to insert records, delete records, search for records.

    Required concepts:Search key: Describe what we are looking forKey comparisonEquality: sequential searchRelative order: sorting

  • Records and KeysProblem: How do we extract the key from a record?Records can have multiple keys.Fundamentally, the key is not a property of the record, but of the context.Solution: We will explicitly store the key with the record.

    *

  • *Dictionary ADTpublic interface Dictionary {

    public void clear(); public void insert(Key k, E e); public E remove(Key k); // Null if none public E removeAny(); // Null if none public E find(Key k); // Null if none public int size();};

  • Payroll Class// Simple payroll entry: ID, name, addressclass Payroll { private Integer ID; private String name; private String address;

    Payroll(int inID, String inname, String inaddr) { ID = inID; name = inname; address = inaddr; }

    public Integer getID() { return ID; } public String getname() { return name; } public String getaddr() { return address; }}

    *

  • Using Dictionary// IDdict organizes Payroll records by IDDictionary IDdict = new UALdictionary();

    // namedict organizes Payroll records by nameDictionary namedict = new UALdictionary();

    Payroll foo1 = new Payroll(5, "Joe", "Anytown");Payroll foo2 = new Payroll(10, "John", "Mytown");IDdict.insert(foo1.getID(), foo1);IDdict.insert(foo2.getID(), foo2);namedict.insert(foo1.getname(), foo1);namedict.insert(foo2.getname(), foo2);Payroll findfoo1 = IDdict.find(5);Payroll findfoo2 = namedict.find("John");

    *

  • *Unsorted List Dictionaryclass UALdictionary implements Dictionary {

    private static final int defaultSize = 10; private AList list;

    // Constructors UALdictionary() { this(defaultSize); } UALdictionary(int sz) { list = new AList(sz); }

    public void clear() { list.clear(); }

    /** Insert an element: append to list */ public void insert(Key k, E e) { KVpair temp = new KVpair(k, e); list.append(temp); }

  • Sorted vs. Unsorted List DictionariesIf list were sortedCould use binary search to speed searchWould need to insert in order, slowing insertWhich is better?If lots of searches, sorted list is goodIf inserts are as likely as searches, then sorting is no benefit.*

  • *Binary TreesA binary tree is made up of a finite set of nodes that is either empty or consists of a node called the root together with two binary trees, called the left and right subtrees, which are disjoint from each other and from the root.

  • *Binary Tree ExampleNotation: Node, children, edge, parent, ancestor, descendant, path, depth, height, level, leaf node, internal node, subtree.

  • *Full and Complete Binary TreesFull binary tree: Each node is either a leaf or internal node with exactly two non-empty children.

    Complete binary tree: If the height of the tree is d, then all leaves except possibly level d are completely full. The bottom level has all nodes to the left side.

  • *Full Binary Tree Theorem (1)Theorem: The number of leaves in a non-empty full binary tree is one more than the number of internal nodes.

    Proof (by Mathematical Induction):

    Base case: A full binary tree with 1 internal node must have two leaf nodes.

    Induction Hypothesis: Assume any full binary tree T containing n-1 internal nodes has n leaves.

  • *Full Binary Tree Theorem (2)Induction Step: Given tree T with n internal nodes, pick internal node I with two leaf children. Remove Is children, call resulting tree T.

    By induction hypothesis, T is a full binary tree with n leaves.

    Restore Is two children. The number of internal nodes has now gone up by 1 to reach n. The number of leaves has also gone up by 1.

  • *Full Binary Tree CorollaryTheorem: The number of null pointers in a non-empty tree is one more than the number of nodes in the tree.

    Proof: Replace all null pointers with a pointer to an empty leaf node. This is a full binary tree.

  • *Binary Tree Node Class/** ADT for binary tree nodes */public interface BinNode { /** Return and set the element value */ public E element(); public E setElement(E v);

    /** Return the left child */ public BinNode left();

    /** Return the right child */ public BinNode right();

    /** Return true if this is a leaf node */ public boolean isLeaf();}

  • *Traversals (1)Any process for visiting the nodes in some order is called a traversal.

    Any traversal that lists every node in the tree exactly once is called an enumeration of the trees nodes.

  • *Traversals (2)Preorder traversal: Visit each node before visiting its children.Postorder traversal: Visit each node after visiting its children.Inorder traversal: Visit the left subtree, then the node, then the right subtree.

  • *Traversals (3)/** @param rt The root of the subtree */void preorder(BinNode rt){ if (rt == null) return; // Empty subtree visit(rt); preorder(rt.left()); preorder(rt.right());}

    // This implementation is error pronevoid preorder(BinNode rt) // Not so good{ visit(rt); if (rt.left() != null) preorder2(rt.left()); if (rt.right() != null) preorder2(rt.right());}

  • *Recursion Examplesint count(BinNode rt) { if (rt == null) return 0; return 1 + count(rt.left()) + count(rt.right());}

    boolean checkBST(BinNode rt, Integer low, Integer high) { if (rt == null) return true; Integer rootkey = rt.key(); if ((rootkey < low) || (rootkey > high)) return false; // Out of range if (!checkBST(rt.left(), low, rootkey)) return false; // Left side failed return checkBST(rt.right(), rootkey, high);}

  • *Binary Tree Implementation (1)

  • *Binary Tree Implementation (2)

  • *Inheritance (1)/** Base class */public interface VarBinNode { public boolean isLeaf();}

    /** Leaf node */class VarLeafNode implements VarBinNode { private String operand; public VarLeafNode(String val) { operand = val; } public boolean isLeaf() { return true; } public String value() { return operand; }};

  • *Inheritance (2)

    /** Internal node */class VarIntlNode implements VarBinNode { private VarBinNode left; private VarBinNode right; private Character operator;

    public VarIntlNode(Character op, VarBinNode l, VarBinNode r) { operator = op; left = l; right = r; } public boolean isLeaf() { return false; } public VarBinNode leftchild() { return left; } public VarBinNode rightchild(){ return right; } public Character value() { return operator; }}

  • *Inheritance (3)

    /** Preorder traversal */public static void traverse(VarBinNode rt) { if (rt == null) return; if (rt.isLeaf()) Visit.VisitLeafNode(((VarLeafNode)rt).value()); else { Visit.VisitInternalNode( ((VarIntlNode)rt).value()); traverse(((VarIntlNode)rt).leftchild()); traverse(((VarIntlNode)rt).rightchild()); }}

  • Design PatternsDesign patterns capture reusable pieces of design wisdom.Goals:Quickly communicate design wisdom to new designersGive a shared vocabulary to designers*

  • *Composite Design Pattern (1)

    /* Base class: Composite */public interface VarBinNode { public boolean isLeaf(); public void traverse();}

    /* Leaf node: Composite */class VarLeafNode implements VarBinNode { private String operand;

    public VarLeafNode(String val) { operand = val; } public boolean isLeaf() { return true; } public String value() { return operand; }

    public void traverse() { Visit.VisitLeafNode(operand); }}

  • *Composite (2)

    /** Internal node: Composite */class VarIntlNode implements VarBinNode { private VarBinNode left; private VarBinNode right; private Character operator;

    public VarIntlNode(Character op, VarBinNode l, VarBinNode r) { operator = op; left = l; right = r; } public boolean isLeaf() { return false; } public VarBinNode leftchild() { return left; } public VarBinNode rightchild() { return right; } public Character value() { return operator; }

    public void traverse() { Visit.VisitInternalNode(operator); if (left != null) left.traverse(); if (right != null) right.traverse(); }}

  • *Composite (3)

    /** Preorder traversal */public static void traverse(VarBinNode rt) { if (rt != null) rt.traverse();}

  • *Space Overhead (1)From the Full Binary Tree Theorem:Half of the pointers are null.

    If leaves store only data, then overhead depends on whether the tree is full.

    Ex: Full tree, all nodes the same, with two pointers to children and one to element:Total space required is (3p + d)nOverhead: 3pnIf p = d, this means 3p/(3p + d) = 3/4 overhead.

  • *Space Overhead (2)Eliminate pointers from the leaf nodes:

    n/2(2p) p n/2(2p) + dn p + d

    This is 1/2 if p = d.

    (2p)/(2p + d) if data only at leaves 2/3 overhead.

    Note that some method is needed to distinguish leaves from internal nodes. =

  • *Binary Search TreesBST Property: All elements stored in the left subtree of a node with value K have values < K. All elements stored in the right subtree of a node with value K have values >= K.

  • *BSTNode (1)class BSTNode implements BinNode { private K key; private E element; private BSTNode left; private BSTNode right;

    public BSTNode() {left = right = null; } public BSTNode(K k, E val) { left = right = null; key = k; element = val; } public BSTNode(K k, E val, BSTNode l, BSTNode r) { left = l; right = r; key = k; element = val; }

    public K key() { return key; } public K setKey(K k) { return key = k; }

    public E element() { return element; } public E setElement(E v) { return element = v; }

  • *BSTNode (2) public BSTNode left() { return left; } public BSTNode setLeft(BSTNode p) { return left = p; }

    public BSTNode right() { return right; } public BSTNode setRight(BSTNode p) { return right = p; }

    public boolean isLeaf() { return (left == null) && (right == null); }}

  • *BST (1)/** BST implementation for Dictionary ADT */class BST
  • *BST (2) /** Remove a record from the tree. @param k Key value of record to remove. @return Record removed, or null if there is none. */ public E remove(K k) { E temp = findhelp(root, k); // find it if (temp != null) { root = removehelp(root, k); // remove it nodecount--; } return temp; }

  • *BST (3) /** Remove/return root node from dictionary. @return The record removed, null if empty. */ public E removeAny() { if (root != null) { E temp = root.element(); root = removehelp(root, root.key()); nodecount--; return temp; } else return null; }

    /** @return Record with key k, null if none. @param k The key value to find. */ public E find(K k) { return findhelp(root, k); }

    /** @return Number of records in dictionary. */ public int size() { return nodecount; }}

  • *BST Searchprivate E findhelp(BSTNode rt, K k) { if (rt == null) return null; if (rt.key().compareTo(k) > 0) return findhelp(rt.left(), k); else if (rt.key().compareTo(k) == 0) return rt.element(); else return findhelp(rt.right(), k);}

  • *BST Insert (1)

  • *BST Insert (2)private BSTNode inserthelp(BSTNode rt, K k, E e) { if (rt == null) return new BSTNode(k, e); if (rt.key().compareTo(k) > 0) rt.setLeft(inserthelp(rt.left(), k, e)); else rt.setRight(inserthelp(rt.right(), k, e)); return rt;}

  • *Get/Remove Minimum Valueprivate BSTNode getmin(BSTNode rt) { if (rt.left() == null) return rt; else return getmin(rt.left());}

    private BSTNode deletemin(BSTNode rt) { if (rt.left() == null) return rt.right(); else { rt.setLeft(deletemin(rt.left())); return rt; }}

  • *BST Remove (1)

  • *BST Remove (2)/** Remove a node with key value k @return The tree with the node removed */private BSTNode removehelp(BSTNode rt, K k) { if (rt == null) return null; if (rt.key().compareTo(k) > 0) rt.setLeft(removehelp(rt.left(), k)); else if (rt.key().compareTo(k) < 0) rt.setRight(removehelp(rt.right(), k));

  • *BST Remove (3) else { // Found it, remove it if (rt.left() == null) return rt.right(); else if (rt.right() == null) return rt.left(); else { // Two children BSTNode temp = getmin(rt.right()); rt.setElement(temp.element()); rt.setKey(temp.key()); rt.setRight(deletemin(rt.right())); } } return rt;}

  • *Time Complexity of BST OperationsFind: O(d)

    Insert: O(d)

    Delete: O(d)

    d = depth of the tree

    d is O(log n) if tree is balanced. What is the worst case?

  • *Array Implementation (1)

    Position01234567891011Parent--00112233445Left Child1357911------------Right Child246810--------------Left Sibling----1--3--5--7--9--Right Sibling--2--4--6--8--10----

  • *Array Implementation (1)Parent (r) =

    Leftchild(r) =

    Rightchild(r) =

    Leftsibling(r) =

    Rightsibling(r) =

  • *Priority Queues (1)Problem: We want a data structure that stores records as they come (insert), but on request, releases the record with the greatest value (removemax)

    Example: Scheduling jobs in a multi-tasking operating system.

  • *Priority Queues (2)Possible Solutions:insert appends to an array or a linked list ( O(1) ) and then removemax determines the maximum by scanning the list ( O(n) )A linked list is used and is in decreasing order; insert places an element in its correct position ( O(n) ) and removemax simply removes the head of the list ( O(1) ).Use a heap both insert and removemax are O( log n ) operations

  • *HeapsHeap: Complete binary tree with the heap property:Min-heap: All values less than child values.Max-heap: All values greater than child values.

    The values are partially ordered.

    Heap representation: Normally the array-based complete binary tree representation.

  • *Max Heap Example88 85 83 72 73 42 57 6 48 60

  • *Max Heap Implementation (1)public class MaxHeap
  • *Sift Downpublic void buildheap() // Heapify contents { for (int i=n/2-1; i>=0; i--) siftdown(i); }

    private void siftdown(int pos) { assert (pos >= 0) && (pos < n) : "Illegal heap position"; while (!isLeaf(pos)) { int j = leftchild(pos); if ((j= 0) return; DSutil.swap(Heap, pos, j); pos = j; // Move down }}

  • *RemoveMax, Insert

    public E removemax() { assert n > 0 : "Removing from empty heap"; DSutil.swap(Heap, 0, --n); if (n != 0) siftdown(0); return Heap[n];}

    public void insert(E val) { assert n < size : "Heap is full"; int curr = n++; Heap[curr] = val; // Siftup until curr parent's key > curr key while ((curr != 0) && (Heap[curr].compareTo(Heap[parent(curr)]) > 0)) { DSutil.swap(Heap, curr, parent(curr)); curr = parent(curr); }}

  • Example of Root DeletionGiven the initial heap:In a heap of N nodes, the maximum distance the root can sift down would be log (N+1) - 1.

  • Heap Building AnalysisInsert into the heap one value at a time: Push each new value down the tree from the root to where it belongs S log i = Q(n log n)Starting with full array, work from bottom upSince nodes below form a heap, just need to push current node down (at worst, go to bottom)Most nodes are at the bottom, so not far to go When i is the level of the node counting from the bottom starting with 1, this is S (i-1) n/2i = Q(n).*

  • *Huffman Coding TreesASCII codes: 8 bits per character.Fixed-length coding.

    Can take advantage of relative frequency of letters to save space.Variable-length coding

    Build the tree with minimum external path weight.

    ZKMCUDLE272432374242120

  • *Huffman Tree Construction (1)

  • *Huffman Tree Construction (2)

  • *Assigning Codes

    LetterFreqCodeBitsC32D42E120M24K7L42U37Z2

  • *Coding and DecodingA set of codes is said to meet the prefix property if no code in the set is the prefix of another.

    Code for DEED:

    Decode 1011001110111101:

    Expected cost per letter:

  • Search Tree vs. TrieIn a BST, the root value splits the key range into everything less than or greater than the keyThe split points are determined by the data valuesView Huffman tree as a search treeAll keys starting with 0 are in the left branch, all keys starting with 1 are in the right branchThe root splits the key range in halfThe split points are determined by the data structure, not the data valuesSuch a structure is called a Trie*

  • *General Trees

  • *General Tree Nodeinterface GTNode { public E value(); public boolean isLeaf(); public GTNode parent(); public GTNode leftmostChild(); public GTNode rightSibling(); public void setValue(E value); public void setParent(GTNode par); public void insertFirst(GTNode n); public void insertNext(GTNode n); public void removeFirst(); public void removeNext();}

  • *General Tree Traversal/** Preorder traversal for general trees */static void preorder(GTNode rt) { PrintNode(rt); if (!rt.isLeaf()) { GTNode temp = rt.leftmostChild(); while (temp != null) { preorder(temp); temp = temp.rightSibling(); } }}

  • Parent Pointer Implementation

  • Equivalence Class ProblemThe parent pointer representation is good for answering:Are two elements in the same tree?

    /** Determine if nodes in different trees */public boolean differ(int a, int b) { Integer root1 = FIND(array[a]); Integer root2 = FIND(array[b]); return root1 != root2;}

  • Union/Find/** Merge two subtrees */public void UNION(int a, int b) { Integer root1 = FIND(a); // Find as root Integer root2 = FIND(b); // Find bs root if (root1 != root2) array[root2] = root1;}

    public Integer FIND(Integer curr) { if (array[curr] == null) return curr; while (array[curr] != null) curr = array[curr]; return curr;}

    Want to keep the depth small.

    Weighted union rule: Join the tree with fewer nodes to the tree with more nodes.

  • Equiv Class Processing (1)

  • Equiv Class Processing (2)

  • Path Compressionpublic Integer FIND(Integer curr) { if (array[curr] == null) return curr; array[curr] = FIND(array[curr]); return array[curr];}

  • *Lists of Children

  • *Leftmost Child/Right Sibling (1)

  • *Leftmost Child/Right Sibling (2)

  • *Linked Implementations (1)

  • *Linked Implementations (2)

  • Efficient Linked Implementation*

  • *Sequential Implementations (1)List node values in the order they would be visited by a preorder traversal.

    Saves space, but allows only sequential access.

    Need to retain tree structure for reconstruction.

    Example: For binary trees, us a symbol to mark null links.AB/D//CEG///FH//I//For full binary trees, use a bit to indicate internal nodes.AB/DCEG/FHI

  • *Sequential Implementations (2)Example: For general trees, mark the end of each subtree.

    RAC)D)E))BF)))

  • SortingEach record contains a field called the key.Linear order: comparison.

    Measures of cost:ComparisonsSwaps

  • Insertion Sort (1)

  • Insertion Sort (2)static
  • Bubble Sort (1)

  • Bubble Sort (2)static
  • Selection Sort (1)

  • Selection Sort (2)static
  • Pointer Swapping

  • Summary

    InsertionBubbleSelectionComparisons:Best Case(n)Q(n2)Q(n2)Average CaseQ(n2)Q(n2)Q(n2)Worst CaseQ(n2)Q(n2)Q(n2)SwapsBest Case00(n)Average CaseQ(n2)Q(n2)(n)Worst CaseQ(n2)Q(n2)(n)

  • Exchange SortingAll of the sorts so far rely on exchanges of adjacent records.

    What is the average number of exchanges required?There are n! permutationsConsider permuation X and its reverse, XTogether, every pair requires n(n-1)/2 exchanges.

  • Shellsort

  • Shellsortstatic
  • Quicksortstatic
  • Quicksort Partitionstatic
  • Partition Example

  • Quicksort Example

  • Cost of QuicksortBest case: Always partition in half.Worst case: Bad partition.Average case:T(n) = n + 1 + 1/(n-1) (T(k) + T(n-k))

    Optimizations for Quicksort:Better PivotBetter algorithm for small sublistsEliminate recursionk=1n-1

  • MergesortList mergesort(List inlist) { if (inlist.length()
  • Mergesort Implementationstatic
  • Optimized Mergesortvoid mergesort(E[] A, E[] temp, int l, int r) { int i, j, k, mid = (l+r)/2; if (l == r) return; // List has one element if ((mid-l) >= THRESHOLD) mergesort(A, temp, l, mid); else inssort(A, l, mid-l+1); if ((r-mid) > THRESHOLD) mergesort(A, temp, mid+1, r); else inssort(A, mid+1, r-mid); // Do merge. First, copy 2 halves to temp. for (i=l; i
  • Mergesort CostMergesort cost:

    Mergsort is also good for sorting linked lists.

    Mergesort requires twice the space.

  • Heapsortstatic
  • Heapsort Example (1)

  • Heapsort Example (2)

  • Binsort (1)A simple, efficient sort:

    for (i=0; i

  • Binsort (2)static void binsort(Integer A[]) { List[] B = (LList[])new LList[MaxKey]; Integer item; for (int i=0; i
  • Radix Sort (1)

  • Radix Sort (2)static void radix(Integer[] A, Integer[] B, int k, int r, int[] count) { int i, j, rtok;

    for (i=0, rtok=1; i

  • Radix Sort Example

  • Radix Sort CostCost: Q(nk + rk)

    How do n, k, and r relate?

    If key range is small, then this can be Q(n).

    If there are n distinct keys, then the length of a key must be at least log n.Thus, Radix Sort is Q(n log n) in general case

  • Empirical Comparison

    Sort101001K10K100K1MUpDownInsertion.00023.0070.66 64.98 7281.0 674420 0.04129.05Bubble.00035.0202.25277.9427691.0282068070.64108.69Selection.00039.0120.69 72.47 7356.0 78000069.76 69.58Shell.00034.0080.14 1.99 30.2 554 0.44 0.79Shell/O.00034.0080.12 1.91 29.0 530 0.36 0.64Merge.00050.0100.12 1.61 19.3 219 0.83 0.79Merge/O.00024.0070.10 1.31 17.2 197 0.47 0.66Quick.00048.0080.11 1.37 15.7 162 0.37 0.40Quick/O.00031.0060.09 1.14 13.6 143 0.32 0.36Heap.00050.0110.16 2.08 26.7 391 1.57 1.56Heap/O.00033.0070.11 1.61 20.8 334 1.01 1.04Radix/4.00838.0810.79 7.99 79.9 808 7.97 7.97Radix/8.00799.0440.40 3.99 40.0 404 4.00 3.99

  • Sorting Lower BoundWe would like to know a lower bound for all possible sorting algorithms.

    Sorting is O(n log n) (average, worst cases) because we know of algorithms with this upper bound.

    Sorting I/O takes (n) time.

    We will now prove (n log n) lower bound for sorting.

  • Decision Trees

  • Lower Bound ProofThere are n! permutations.A sorting algorithm can be viewed as determining which permutation has been input.Each leaf node of the decision tree corresponds to one permutation.A tree with n nodes has W(log n) levels, so the tree with n! leaves has W(log n!) = W(n log n) levels.

    Which node in the decision tree corresponds to the worst case?

  • Programmers View of FilesLogical view of files:An a array of bytes.A file pointer marks the current position.

    Three fundamental operations:Read bytes from current position (move file pointer)Write bytes to current position (move file pointer)Set file pointer to specified byte position.

  • Java File FunctionsRandomAccessFile(String name, String mode)

    close()

    read(byte[] b)

    write(byte[] b)

    seek(long pos)

  • Primary vs. Secondary StoragePrimary storage: Main memory (RAM)

    Secondary Storage: Peripheral devicesDisk drivesTape drivesFlash drives

  • Comparisons

    RAM is usually volatile.

    RAM is about 1/2 million times faster than disk.

    Medium19961997200020004200620072008RAM$45.007.001.5000.35000.15000.07420.0339Disk 0.250.100.0100.00100.00050.00040.0001Flash ---------- -----0.10000.09000.00980.0029Floppy 0.500.360.2500.2500 ---------------Tape 0.030.010.0010.0003 ---------------

  • Golden Rule of File ProcessingMinimize the number of disk accesses!

    1. Arrange information so that you get what you want with few disk accesses.2. Arrange information to minimize future disk accesses.

    An organization for data on disk is often called a file structure.

    Disk-based space/time tradeoff: Compress information to save processing time by reducing disk accesses.

  • Disk Drives

  • Sectors

    A sector is the basic unit of I/O.

  • TermsLocality of Reference: When record is read from disk, next request is likely to come from near the same place on the disk.

    Cluster: Smallest unit of file allocation, usually several sectors.

    Extent: A group of physically contiguous clusters.

    Internal fragmentation: Wasted space within sector if record size does not match sector size; wasted space within cluster if file size is not a multiple of cluster size.

  • Seek TimeSeek time: Time for I/O head to reach desired track. Largely determined by distance between I/O head and desired track.

    Track-to-track time: Minimum time to move from one track to an adjacent track.

    Average Access time: Average time to reach a track for random access.

  • Other FactorsRotational Delay or Latency: Time for data to rotate under I/O head.One half of a rotation on average.At 7200 rpm, this is 8.3/2 = 4.2ms.

    Transfer time: Time for data to move under the I/O head.At 7200 rpm: Number of sectors read/Number of sectors per track * 8.3ms.

  • Disk Spec Example16.8 GB disk on 10 platters = 1.68GB/platter13,085 tracks/platter256 sectors/track512 bytes/sectorTrack-to-track seek time: 2.2 msAverage seek time: 9.5ms4KB clusters, 32 clusters/track.5400RPM

  • Disk Access Cost Example (1)Read a 1MB file divided into 2048 records of 512 bytes (1 sector) each.

    Assume all records are on 8 contiguous tracks.

    First track: 9.5 + (11.1)(1.5) = 26.2 ms

    Remaining 7 tracks: 2.2 + (11.1)(1.5) = 18.9ms.

    Total: 26.2 + 7 * 18.9 = 158.5ms

  • Disk Access Cost Example (2)Read a 1MB file divided into 2048 records of 512 bytes (1 sector) each.

    Assume all file clusters are randomly spread across the disk.

    256 clusters. Cluster read time is 8/256 of a rotation for about 5.9ms for both latency and read time.

    256(9.5 + 5.9) is about 3942ms or nearly 4 sec.

  • How Much to Read?Read time for one track:9.5 + (11.1)(1.5) = 26.2ms

    Read time for one sector:9.5 + 11.1/2 + (1/256)11.1 = 15.1ms

    Read time for one byte:9.5 + 11.1/2 = 15.05ms

    Nearly all disk drives read/write one sector (or more) at every I/O accessAlso referred to as a page or block

  • More Recent Drive SpecsSamsung Spinpoint T166500GB (nominal)7200 RPMTrack to track: 0.8 msAverage track access: 8.9 msBytes/sector 5126 surfaces/heads*

  • BuffersThe information in a sector is stored in a buffer or cache.

    If the next I/O access is to the same buffer, then no need to go to disk.

    There are usually one or more input buffers and one or more output buffers.

  • Buffer PoolsA series of buffers used by an application to cache disk data is called a buffer pool.

    Virtual memory uses a buffer pool to imitate greater RAM memory by actually storing information on disk and swapping between disk and RAM.

  • Buffer Pools

  • Organizing Buffer PoolsWhich buffer should be replaced when new data must be read?

    First-in, First-out: Use the first one on the queue.

    Least Frequently Used (LFU): Count buffer accesses, reuse the least used.

    Least Recently used (LRU): Keep buffers on a linked list. When buffer is accessed, bring it to front. Reuse the one at end.

  • Bufferpool ADT: Message Passing/** Buffer pool: message-passing style */public interface BufferPoolADT { /** Copy "sz" bytes from "space" to position "pos" in the buffered storage */ public void insert(byte[] space, int sz, int pos); /** Copy "sz" bytes from position "pos" of the buffered storage to "space". */ public void getbytes(byte[] space, int sz, int pos);}

  • Bufferpool ADT: Buffer Passing/** Buffer pool: buffer-passing style */public interface BufferPoolADT { /** Return pointer to requested block */ public byte[] getblock(int block);

    /** Set the dirty bit for the buffer holding "block" */ public void dirtyblock(int block);

    /** Tell the size of a buffer */ public int blocksize();}

    *

  • Design IssuesDisadvantage of message passing:Messages are copied and passed back and forth. Disadvantages of buffer passing:The user is given access to system memory (the buffer itself)The user must explicitly tell the buffer pool when buffer contents have been modified, so that modified data can be rewritten to disk when the buffer is flushed. The pointer might become stale when the bufferpool replaces the contents of a buffer.

  • Some GoalsBe able to avoid reading data when the block contents will be replaced.Be able to support multiple users accessing a buffer, and indpendantly releasing a buffer.Dont make an active buffer stale.*

  • Improved Interfacepublic interface BufferPoolADT { Buffer acquireBuffer(int block);}

    public interface BufferADT { // Read the block from disk public byte[] readBlock(); // Just get pointer to space, no read public byte[] getDataPointer(); // Contents have changed public void markDirty(); // Release access to the block public void release();}

    *

  • External SortingProblem: Sorting data sets too large to fit into main memory.Assume data are stored on disk drive.

    To sort, portions of the data must be brought into main memory, processed, and returned to disk.

    An external sort should minimize disk accesses.

  • Model of External ComputationSecondary memory is divided into equal-sized blocks (512, 1024, etc)

    A basic I/O operation transfers the contents of one disk block to/from main memory.

    Under certain circumstances, reading blocks of a file in sequential order is more efficient. (When?)

    Primary goal is to minimize I/O operations.

    Assume only one disk drive is available.

  • Key SortingOften, records are large, keys are small.Ex: Payroll entries keyed on ID number

    Approach 1: Read in entire records, sort them, then write them out again.

    Approach 2: Read only the key values, store with each key the location on disk of its associated record.

    After keys are sorted the records can be read and rewritten in sorted order.

  • Simple External Mergesort (1)Quicksort requires random access to the entire set of records.

    Better: Modified Mergesort algorithm.Process n elements in Q(log n) passes.

    A group of sorted records is called a run.

  • Simple External Mergesort (2)Split the file into two files.Read in a block from each file.Take first record from each block, output them in sorted order.Take next record from each block, output them to a second file in sorted order.Repeat until finished, alternating between output files. Read new input blocks as needed.Repeat steps 2-5, except this time input files have runs of two sorted records that are merged together.Each pass through the files provides larger runs.

  • Simple External Mergesort (3)

  • Problems with Simple MergesortIs each pass through input and output files sequential?

    What happens if all work is done on a single disk drive?

    How can we reduce the number of Mergesort passes?

    In general, external sorting consists of two phases:Break the files into initial runsMerge the runs together into a single run.

  • Breaking a File into RunsGeneral approach:Read as much of the file into memory as possible.Perform an in-memory sort.Output this group of records as a single run.

  • Replacement Selection (1)Break available memory into an array for the heap, an input buffer, and an output buffer.Fill the array from disk.Make a min-heap.Send the smallest value (root) to the output buffer.

  • Replacement Selection (2)If the next key in the file is greater than the last value output, thenReplace the root with this keyelseReplace the root with the last key in the arrayAdd the next record in the file to a new heap (actually, stick it at the end of the array).

  • RS Example

  • Snowplow Analogy (1)Imagine a snowplow moving around a circular track on which snow falls at a steady rate.

    At any instant, there is a certain amount of snow S on the track. Some falling snow comes in front of the plow, some behind.

    During the next revolution of the plow, all of this is removed, plus 1/2 of what falls during that revolution.

    Thus, the plow removes 2S amount of snow.

  • Snowplow Analogy (2)

  • Problems with Simple MergeSimple mergesort: Place runs into two files.Merge the first two runs to output file, then next two runs, etc.

    Repeat process until only one run remains.How many passes for r initial runs?

    Is there benefit from sequential reading?Is working memory well used?Need a way to reduce the number of passes.

  • Multiway Merge (1)With replacement selection, each initial run is several blocks long.

    Assume each run is placed in separate file.

    Read the first block from each file into memory and perform an r-way merge.

    When a buffer becomes empty, read a block from the appropriate run file.

    Each record is read only once from disk during the merge process.

  • Multiway Merge (2)In practice, use only one file and seek to appropriate block.

  • Limits to Multiway Merge (1)Assume working memory is b blocks in size.

    How many runs can be processed at one time?

    The runs are 2b blocks long (on average).

    How big a file can be merged in one pass?

  • Limits to Multiway Merge (2)Larger files will need more passes -- but the run size grows quickly!

    This approach trades (log b) (possibly) sequential passes for a single or very few random (block) access passes.

  • General PrinciplesA good external sorting algorithm will seek to do the following:Make the initial runs as long as possible.At all stages, overlap input, processing and output as much as possible.Use as much working memory as possible. Applying more memory usually speeds processing.If possible, use additional disk drives for more overlapping of processing with I/O, and allow for more sequential file processing.

  • SearchGiven: Distinct keys k1, k2, , kn and collection L of n records of the form(k1, I1), (k2, I2), , (kn, In)where Ij is the information associated with key kj for 1
  • Successful vs. UnsuccessfulA successful search is one in which a record with key kj = K is found.

    An unsuccessful search is one in which no record with kj = K is found (and presumably no such record exists).

  • Approaches to Search1. Sequential and list methods (lists, tables, arrays).

    2. Direct access by key value (hashing)

    3. Tree indexing methods.

  • Average Cost for Sequential SearchHow many comparisons does sequential search do on average?We must know the probability of occurrence for each possible input.Must K be in L?For analysis, ignore everything except the position of K in L. Why?What are the n + 1 events?

  • Average Cost (cont)Let ki = I+1 be the number of comparisons when X = L[i].Let kn = n be the number of comparisons when X is not in L.Let pi be the probability that X = L[i].Let pn be the probability that X is not in L[i] for any I.

  • Generalizing Average CostWhat happens to the equation if we assume all pi's are equal (except p0)?

    Depending on the value of p0,(n+1)/2 < T(n) < n.

  • Searching Ordered ArraysChange the model: Assume that the elements are in ascending order.Is linear search still optimal? Why not?Optimization: Use linear search, but test if the element is greater than K. Why?Observation: If we look at L[5] and find that K is bigger, then we rule out L[1] to L[4] as well.More is Better: If K > L[n], then we know in one test that K is not in L. What is wrong here?

  • Jump SearchWhat is the right amount to jump? Algorithm:Check every k'th element (L[k], L[2k], ...).If K is greater, then go on.If K is less, then use linear search on the k elements. This is called Jump Search.

  • Analysis of Jump SearchIf mk
  • Jump Search Analysis (cont)Take the derivative and solve for T'(x) = 0 to find the minimum. This is a minimum when What is the worst case cost? Roughly

  • LessonsWe want to balance the work done while selecting a sublist with the work done while searching a sublist.

    In general, make sub-problems of equal effort.

    This is an example of divide and conquer.

    What if we extend this to three levels?

  • Interpolation Search(Also known as Dictionary Search)

    Search L at a position that is appropriate to the value K.

    Repeat as necessary to recalculate p for future searches.

  • Quadratic Binary Search(This is easier to analyze.)

    Compute p and examine

    If then sequentially probe

    Until we reach a value less than or equal to K.

    Similar for

  • Quadratic Binary Search (cont)We are now within positions of K.

    ASSUME (for now) that this takes a constant number of comparisons.

    We now have a sublist of size .

    Repeat the process recursively.

    What is the cost?

  • QBS Probe CountQBS cost is Q(log log n) if the number of probes on jump search is constant.

    From Cebysevs inequality, we can show that on uniformly distributed data, the average number of probes required will be about 2.4.

    Is this better than binary search? Theoretically, yes (in the average case).

  • Comparison

    nlog nlog log nDiff16422256832.764k16442323256.4

    nlog n-12.4 log log nDiff1634.8worse25677.2same64k159.61.623231122.6

  • Lists Ordered by FrequencyOrder lists by (expected) frequency of occurrence.Perform sequential search

    Cost to access first record: 1Cost to access second record: 2

    Expected search cost:

  • Examples(1)(1) All records have equal frequency.

  • Examples(2)(2) Geometric Frequency

  • Zipf DistributionsApplications:Distribution for frequency of word usage in natural languages.Distribution for populations of cities, etc.

    80/20 rule:80% of accesses are to 20% of the records.For distributions following 80/20 rule,

  • Self-Organizing ListsSelf-organizing lists modify the order of records within the list based on the actual pattern of record accesses.

    Self-organizing lists use a heuristic for deciding how to reorder the list. These heuristics are similar to the rules for managing buffer pools.

  • HeuristicsOrder by actual historical frequency of access. (Similar to LFU buffer pool replacement strategy.)When a record is found, swap it with the first record on list.Move-to-Front: When a record is found, move it to the front of the list.Transpose: When a record is found, swap it with the record ahead of it.

  • Text Compression ExampleApplication: Text Compression.

    Keep a table of words already seen, organized via Move-to-Front heuristic.If a word not yet seen, send the word.Otherwise, send (current) index in the table.

    The car on the left hit the car I left.The car on 3 left hit 3 5 I 5.

    This is similar in spirit to Ziv-Lempel coding.

  • Searching in SetsFor dense sets (small range, high percentage of elements in set).

    Can use logical bit operators.

    Example: To find all primes that are odd numbers, compute:0011010100010100 & 0101010101010101

    Document processing: Signature files

  • *IndexingGoals:Store large filesSupport multiple search keysSupport efficient insert, delete, and range queries

  • *Files and IndexingEntry sequenced file: Order records by time of insertion.Search with sequential search

    Index file: Organized, stores pointers to actual records.Could be organized with a tree or other data structure.

  • *Keys and IndexingPrimary Key: A unique identifier for records. May be inconvenient for search.

    Secondary Key: An alternate search key, often not unique for each record. Often used for search key.

  • *Linear Indexing (1)Linear index: Index file organized as a simple sequence of key/record pointer pairs with key values are in sorted order.

    Linear indexing is good for searching variable-length records.

  • *Linear Indexing (2)If the index is too large to fit in main memory, a second-level index might be used.

  • *Tree Indexing (1)Linear index is poor for insertion/deletion.

    Tree index can efficiently support all desired operations:Insert/deleteMultiple search keys (multiple indices)Key range search

  • *Tree Indexing (2)Difficulties when storing tree index on disk:Tree must be balanced.Each path from root to leaf should cover few disk pages.

  • *2-3 TreeA 2-3 Tree has the following properties:A node contains one or two keysEvery internal node has either two children (if it contains one key) or three children (if it contains two keys).All leaves are at the same level in the tree, so the tree is always height balanced.

    The 2-3 Tree has a search tree property analogous to the BST.

  • *2-3 Tree ExampleThe advantage of the 2-3 Tree over the BST is that it can be updated at low cost.

  • *2-3 Tree Insertion (1)

  • *2-3 Tree Insertion (2)

  • *2-3 Tree Insertion (3)

  • *B-Trees (1)The B-Tree is an extension of the 2-3 Tree.

    The B-Tree is now the standard file organization for applications requiring insertion, deletion, and key range searches.

  • *B-Trees (2)B-Trees are always balanced.B-Trees keep similar-valued records together on a disk page, which takes advantage of locality of reference.B-Trees guarantee that every node in the tree will be full at least to a certain minimum percentage. This improves space efficiency while reducing the typical number of disk fetches necessary during a search or update operation.

  • *B-Tree DefinitionA B-Tree of order m has these properties:The root is either a leaf or has two children.Each node, except for the root and the leaves, has between m/2 and m children.All leaves are at the same level in the tree, so the tree is always height balanced.

    A B-Tree node is usually selected to match the size of a disk block.A B-Tree node could have hundreds of children.

  • *B-Tree SearchGeneralizes search in a 2-3 Tree.Do binary search on keys in current node. If search key is found, then return record. If current node is a leaf node and key is not found, then report an unsuccessful search.Otherwise, follow the proper branch and repeat the process.

  • *B+-TreesThe most commonly implemented form of the B-Tree is the B+-Tree.

    Internal nodes of the B+-Tree do not store record -- only key values to guild the search.

    Leaf nodes store records or pointers to records.

    A leaf node may store more or less records than an internal node stores keys.

  • *B+-Tree Example

  • *B+-Tree Insertion

  • *B+-Tree Deletion (1)

  • *B+-Tree Deletion (2)

  • *B+-Tree Deletion (3)

  • *B-Tree Space Analysis (1)B+-Trees nodes are always at least half full.

    The B*-Tree splits two pages for three, and combines three pages into two. In this way, nodes are always 2/3 full.

    Asymptotic cost of search, insertion, and deletion of nodes from B-Trees is (log n).Base of the log is the (average) branching factor of the tree.

  • *B-Tree Space Analysis (2)Example: Consider a B+-Tree of order 100 with leaf nodes containing 100 records.1 level B+-tree:2 level B+-tree:3 level B+-tree:4 level B+-tree:

    Ways to reduce the number of disk fetches:Keep the upper levels in memory.Manage B+-Tree pages with a buffer pool.

  • GraphsA graph G = (V, E) consists of a set of vertices V, and a set of edges E, such that each edge in E is a connection between a pair of vertices in V.

    The number of vertices is written |V|, and the number edges is written |E|.

  • Graphs (2)

  • Paths and CyclesPath: A sequence of vertices v1, v2, , vn of length n-1 with an edge from vi to vi+1 for 1
  • Connected ComponentsAn undirected graph is connected if there is at least one path from any vertex to any other.

    The maximum connected subgraphs of an undirected graph are called connected components.

  • Directed Representation

  • Undirected Representation

  • Representation CostsAdjacency Matrix:

    Adjacency List:

  • Graph ADTinterface Graph { // Graph class ADT public void Init(int n); // Initialize public int n(); // # of vertices public int e(); // # of edges public int first(int v); // First neighbor public int next(int v, int w); // Neighbor public void setEdge(int i, int j, int wght); public void delEdge(int i, int j); public boolean isEdge(int i, int j); public int weight(int i, int j); public void setMark(int v, int val); public int getMark(int v); // Get vs Mark}

  • Graph TraversalsSome applications require visiting every vertex in the graph exactly once.

    The application may require that vertices be visited in some special order based on graph topology.

    Examples:Artificial Intelligence SearchShortest paths problems

  • Graph Traversals (2)To insure visiting all vertices:

    void graphTraverse(Graph G) { int v; for (v=0; v

  • Depth First Search (1)// Depth first search void DFS(Graph G, int v) { PreVisit(G, v); // Take appropriate action G.setMark(v, VISITED); for (int w = G.first(v); w < G.n(); w = G.next(v, w)) if (G.getMark(w) == UNVISITED) DFS(G, w); PostVisit(G, v); // Take appropriate action}

  • Depth First Search (2)

    Cost: (|V| + |E|).

  • Breadth First Search (1)Like DFS, but replace stack with a queue.Visit vertexs neighbors before continuing deeper in the tree.

  • Breadth First Search (2)

    void BFS(Graph G, int start) { Queue Q = new AQueue(G.n()); Q.enqueue(start); G.setMark(start, VISITED); while (Q.length() > 0) { // For each vertex int v = Q.dequeue(); PreVisit(G, v); // Take appropriate action for (int w = G.first(v); w < G.n(); w = G.next(v, w)) if (G.getMark(w) == UNVISITED) { // Put neighbors on Q G.setMark(w, VISITED); Q.enqueue(w); } PostVisit(G, v); // Take appropriate action }}

  • Breadth First Search (3)

  • Topological Sort (1)Problem: Given a set of jobs, courses, etc., with prerequisite constraints, output the jobs in an order that does not violate any of the prerequisites.

  • Topological Sort (2)void topsort(Graph G) { for (int i=0; i
  • Topological Sort (3)

  • Queue-Based Topsortvoid topsort(Graph G) { Queue Q = new AQueue(G.n()); int[] Count = new int[G.n()]; int v, w; for (v=0; v
  • Shortest Paths ProblemsInput: A graph with weights or costs associated with each edge.

    Output: The list of edges forming the shortest path.

    Sample problems:Find shortest path between two named verticesFind shortest path from S to all other verticesFind shortest path between all pairs of vertices

    Will actually calculate only distances.

  • Shortest Paths Definitionsd(A, B) is the shortest distance from vertex A to B.

    w(A, B) is the weight of the edge connecting A to B.If there is no such edge, then w(A, B) = .

  • Single-Source Shortest PathsGiven start vertex s, find the shortest path from s to all other vertices.

    Try 1: Visit vertices in some order, compute shortest paths for all vertices seen so far, then add shortest path to next vertex x.

    Problem: Shortest path to a vertex already processed might go through x.Solution: Process vertices in order of distance from s.

  • Example Graph

  • Dijkstras Algorithm Example

    ABCDEInitial0Process A010320Process C0532018Process B0531018Process D0531018Process E0531018

  • Dijkstras Implementation// Compute shortest path distances from s,// store them in Dvoid Dijkstra(Graph G, int s, int[] D) { for (int i=0; i
  • Implementing minVertexIssue: How to determine the next-closest vertex? (I.e., implement minVertex)

    Approach 1: Scan through the table of current distances.Cost: Q(|V|2 + |E|) = Q(|V|2).

    Approach 2: Store unprocessed vertices using a min-heap to implement a priority queue ordered by D value. Must update priority queue for each edge.Cost: Q((|V| + |E|)log|V|)

  • Approach 1int minVertex(Graph G, int[] D) { int v = 0; // Initialize to unvisited vertex; for (int i=0; i
  • Approach 2void Dijkstra(Graph G, int s, int[] D) { int v, w; DijkElem[] E = new DijkElem[G.e()]; E[0] = new DijkElem(s, 0); MinHeap H = new MinHeap(E, 1, G.e()); for (int i=0; i
  • Minimal Cost Spanning TreesMinimal Cost Spanning Tree (MST) Problem:

    Input: An undirected, connected graph G.Output: The subgraph of G that 1) has minimum total cost as measured by summing the values of all the edges in the subset, and 2) keeps the vertices connected.

  • MST Example

  • Prims MST Algorithm// Compute a minimal-cost spanning treevoid Prim(Graph G, int s, int[] D, int[] V) { int v, w; for (int i=0; i
  • Alternate ImplementationAs with Dijkstras algorithm, the key issue is determining which vertex is next closest.

    As with Dijkstras algorithm, the alternative is to use a priority queue.

    Running times for the two implementations are identical to the corresponding Dijkstras algorithm implementations.

  • Kruskals MST Algorithm (1)Initially, each vertex is in its own MST.

    Merge two MSTs that have the shortest edge between them.Use a priority queue to order the unprocessed edges. Grab next one at each step.

    How to tell if an edge connects two vertices already in the same MST?Use the UNION/FIND algorithm with parent-pointer representation.

  • Kruskals MST Algorithm (2)

  • Kruskals MST Algorithm (3)Cost is dominated by the time to remove edges from the heap.Can stop processing edges once all vertices are in the same MST

    Total cost: Q(|V| + |E| log |E|).

    **The first goal is a worldview to adopt

    The second goal is the nuts and bolts of the course.

    The third goal prepares a student for the future.

    To handle the content: Each day before class, spend 5-10 minutes reviewing the material covered in the last class.To handle the projects: Make and stick to a schedule that spreads the works sensibly over time, so that you are not working on the project at the last minute.**A primary concern for this course is efficiency.

    You might believe that faster computers make it unnecessary to be concerned with efficiency. However

    So we need special training.

    *Alternate definition: Better than known alternatives (relatively efficient).

    Space and time are typical constraints for programs.

    This does not mean always strive for the most efficient program. If the program operates well within resource constraints, there is no benefit to making it faster or smaller.*Typically want the simplest data structure that will meet the requirements.*The space required includes data and overhead.

    Some data structures/algorithms are more complicated than others.

    **These questions often help to narrow the possibilities.

    If data can be deleted, a more complex representation is typically required.

    *****In this class, we frequently move above and below the line separating logical and physical forms.********Look over Chapter 2, read as needed depending on your familiarity with this material.

    A set has no duplicates, a sequence may have duplicates.

    Logarithms: We almost always use log to base 2. That is our default base.*Look over Chapter 2, read as needed depending on your familiarity with this material.

    A set has no duplicates, a sequence may have duplicates.

    Logarithms: We almost always use log to base 2. That is our default base.*Pages/inch: Guess 500

    Feet/shelf: Guess 4, actually 3

    Shelves/bookcase: Guess 5, actually 7

    Units check: pages/in x ft/shelf x shelf/bookcase pages/bookcase

    ***Empirical comparison is difficult to do fairly and is time consuming.

    Critical resources: Time. Space (disk, RAM). Programmers effort. Ease of use (users effort).

    Factors affecting running time: Machine load. OS. Compiler. Problem size. Specific input values for given problem size.

    *As n grows, how does T(n) grow?

    Cost: T(n) = c1n + c2 steps

    *Example 2: Constant cost.

    Example 3: Cost: T(n) = c1n2 + c2. Roughly n2 steps, with sum being n2 at the end. Ignore various overhead such as loop counter increments.

    *The lower graph corresponds to the box within the dashed lines in the lower left corner of the upper graph.*Best: Find at first position. Cost is 1 compare.Worst: Find at last position. Cost is n compares.Average: (n+1)/2 compares IF we assume the element with value K is equally likely to be in any position in the array.*Average time analysis requires knowledge of distributions. For example, the assumption of distribution used for average case in the last example.

    Worst-case time is important for real-time algorithms.

    *How much speedup? 10 times. More important: How much increase in problem size for same time expended? That depends on the growth rate.

    n: Size of input that can be processed in one hour (10,000 steps).n: Size of input that can be processed in one our on the new machine (100,000 steps).

    Note: for 2n, if n = 1000, then n would be 1003.

    *Must pick one of [best, average, worst] to complete the statement. Big-oh notation applies to some set of bounds.

    *It provides more information in this example to say O(n2) than O(n3).*We are doing average case.

    cs is a constant. The actual value is irrelevant.

    **We are doing average case.

    cs is a constant. The actual value is irrelevant.

    ***For polynomial equations on T(n), we always have . There is no uncertainty, since once we have the equation, we have a complete analysis.

    **2. Ignore constants.3. Drop low order terms.4. Useful for analyzing loops.

    *Asymptotic analysis is defined for equations. We need to convert programs to equations to analyze them.

    The traditional notation is (1), not (c).(n) even though the value of sum is n2.*First statement is (1). Double for loop is i = (n2). Final for loop is (n). Result: (n2).*The only difference is j