CS211 Final. 9:00-11:30PM, Friday, 14 May 2004. Uris Auditorium. The final is optional —you can accept the grade that is posted on the CMS or take the final. If you do not take the final, you must do project A7 or risk having your letter grade drop one notch (e.g. A to A-). We will attempt to make sure that you have adequate time to answer the questions on the final. We expect people to start walking out after 1.5 hours. Some review questions are given later in this document, and following all the questions are sample andwers. Other review questions are in the handouts for reviewing prelims 1 and 2. You are responsible for everything that was on the first and second prelims. Please see the web page for the handouts explaining what they covered. You are responsible for the following additional material. Graphs 1. Definition of a directed and an undirected graph. 2. Two major ways of implementing a graph: adjacentcy matrix and adjacency list. Know their advantages and disadvantages (with respect to space and time). 3. Dijkstra’s shortest path algorithm. If we ask you to show it, we will give you the invariant. 4. Spanning tree. Know the definition. Know the DFS and BFS spanning tree algorithms. You do NOT have to know about minimum spanning trees. GUIS You do not need to know gory details of GUI classes and their methods. You should have a basic understanding of GUIs, as discussed below. One way to get this understanding is to download the demos GUIs we used in class and read them and execute them and experiment with them. 1. A JFrame jf is a window on your monitor. You have to execute jf.show() to see it. You can place things in a JFrame with its default layout manager, BorderLayout. So, you can place objects in the north, south, east, west, and center. 2. Some of the components that you can place in a JFrame are a JButton, JLabel, JTextField (know what each one is), a JPanel, and a Box. 3. A JPanel is a component that can contain other components. The default layout manager is FlowLayout (you should know how it lays out components). 4. A Box is a component that can contain other components. The default layout manager is BoxLayout (you should know how it lays out components). 5. You should know basically how to get a button to listen to a click on it: Register with the button an instance of a class that implements interface ActionListener. This means that the class contains a method actionPerformed (ActionEvent). This method is called when the button is clicked (in the GUI). Development of algorithms You should be able to develop these algorithms, given their specifications: linear search, binary search, partition algorithm, Dutch national flag, selection sort, quicksort, mergesort, Dijkstra’s shortest path algorithm (for this one only, we will give you the invariant). There are two reasons for asking you to be able to develop these algorithms. (1) These are basic algorithms with which every programmer should be familiar. (2) If you can develop these algorithms from their specs whenever you are asked for them, you are well on your way to developing good programming habits. We do not memorize the code. We memorize the specifications and perhaps one or two keys points. We are then able to develop the algorithm. That is what we would like you to be able to do. The way to learn this is to practice. Don’t just study by reading. Get a fresh piece of paper and try to develop the algorithms yourself. Note that we may give you a variation of the original problem. For example, we may ask you to write selection sort to sort b, to sort b[0..k-1], or to sort b[h..k]. The idea is the same in all of them; the details are different, and it does not help to memorize code. You should know the worst-case and best-case execution times of the algorithms mentioned above. This ends the discussion of what the final will cover. We now give some sample questions (followed by answers). Questions on interfaces and classes Interface and Class 1 Why is a class disallowed from extending several classes (in Java)? Interface and Class 2 Consider the two classes that both implement interface Coin. (Method bodies have been omitted for simplicity.) public class Nickel implements Coin{ public int getValue(){} public String getMetal(){} public short getYear(){} public bool flip(){} } public class Quarter implements Coin{ public int getValue(){} public String getMetal(){} public String getYear(){} } (a) Assuming that these two classes compile, what is the maximum number of methods that can be defined in Coin? What are they? Interface and class 7 Below is class HashSet. –we have left off method specification because they are not needed for this question, and we have omitted method remove() from HashSetEnum. public class HashSet { private HashEntry[] b; private int size; private class HashSetEnum implements Iterator { private int pos= -1; // items in … private int visited= 0; //… (b) If Nickel and Quarter extended a class Coin instead of implementing an interface, how does your answer to 2 change? public boolean hasNext() { return visited != size; } Interface and Class 3 What is wrong with the following code: public Object next() { pos= pos+1; while (pos != b.length && … ) { pos= pos+1; } … } public class Wrong{ int a; public static int value(){ return a; } } } } Interface and Class 4 Consider the following hierarchy, where they nodes could be classes or interfaces (except for Object, which is a class). Is HashSetEnum a nested class or an inner class? Why? Object Object Vehicle MotorVehicle WaterCraft Boat Which of the following expressions are legal? (a) Boat b= new Boat(); (b) WaterCraft wc= (WaterCraft) b; (c) Vehicle v= (Vehicle) wc; (d) MotorVehicle mv= (MotorVehicle) b; (e) MotorVehicle mv2= (MotorVehicle) wc; Interface and class 5 What are the reasons for using a nested class? Get it out of the way; make it private so others can’t refer to it directly. Interface and class 6 (1) What are the reasons for using an inner class (a non-static class that is placed inside another class)? Interface and class 7 Draw a diagram of an instance of HashSet see previous questions) named a1 with size 256 and an instance of HashSetEnum named a3, with the variables pos and visited set to 20 and 3 respectively. Questions on linked lists Linked list 1 A cyclic linked list is a linked list that contains a cycle —one of the nodes in the linked list links to a previous node. Here is an example: A -> B -> C -> D -> E -> F -> G -> C G links back to C, so the cycle is: C D E F G C The linked lists nodes conform to the following class: public class LinkedList { public Object data; public LinkedList next; } Write a method that, given a LinkedList, returns true if the linked list has a cycle and false if it does not. Linked list 2 Count the number of elements in a circular LinkedList (use class definition from previous question). The circular linked list does not use a sentinel or head node Linked list 3 Given are two linked lists that contain ints and are sorted in ascending order. Write a function that returns a new linked list containing all the elements of both linked lists in ascending order. Linked list 4 Given two linked lists, create a new linked list that is the first linked list followed by the second. For example: L1 A->B->C->D->E->F->null L2 Z->Y->X->W->null return A->B->C->D->E->F->Z->Y->X->W>null Questions on binary trees These questions use this class TreeNode: /** = a new binary tree that has the same shape as t but with each datum replaced with the result of calling fn.translate() */ TreeNode treeTrans(Translator fn, TreeNode t Binary tree 3 The following is a sample binary search tree: 6 / \ 3 7 / \ \ 1 5 9 What order would the BST’s nodes be visited for each of the following traversals? Preorder, postorder, inorder Draw the tree after inserting the value 4, followed by inserting the value 10. Draw the two possible trees that could result from deleting the value 6 from the original tree at top: Is the following a BST? Explain why or why not. class TreeNode { Object datum; TreeNode left, right; } Binary tree 1 Write the body of method isMirror() below, which determines whether two binary trees are mirror images of each other. For example, these two trees are mirror images because both the shape and data are reversed left-to-right: A / \ B C / D A / \ C B \ D Hint: Use method equals() declared in Object to determine if two tree nodes contain the same datum (you can assume that no datum value is null). // = “the tree rooted at a is a mirror image of the tree rooted at b” */ public static boolean isMirror(TreeNode a, TreeNode b) Binary tree 2 We define interface Translator, which encapsulates a method that converts the given object to another form. We do not need to know what the original form was, or what the new form is. interface Translator { Object translate(Object ob); } Write the body of method treeTrans(): 7 / \ 5 9 / \ \ 2 8 12 Binary tree 4 An N-tree is a logical extension of the binary trees we have discussed. Instead of each node having 0, 1, or 2 children, nodes in an N-tree can have any number of children. To accomplish this, child nodes make up a linked list called the sibling list. public class NTreeNode { public Object datum; // leftmost child node public NTreeNode firstChild; // next child that shares this node’s parent, or null if // this is the rightmost child public NTreeNode nextSibling; … } Example: In the N-tree below, root node A has three children, and its second child C has two children of its own. A / B—C—D / E—F Write the bodies for the following two methods: // Print out all the data in the tree in preorder public void printNTree(NTreeNode t) // = the number of levels in the tree // (a tree with 0 nodes has 0 levels) int ntreeHeight(NTreeNode t) Binary tree 5 Write the body of method isInHeap() below, which searches for a specific value within a heap. Use method equals() declared in Object to determine if two heap nodes contain the same datum (you can assume that no datum value is null). // = “the heap contains the target value” // Precondition: t is the root of a min- or max-heap public bool isInHeap(TreeNode t, Object target) Write down its worst-case order of execution time assuming a tree containing n nodes, and informally explain your answer. Assume that some method isInBST() exists that operates on balanced binary search trees. Write down the worst-case order of execution time of this method, given a tree of n nodes, and informally explain your answer. Binary tree 6 Write the body of method treeMax() below, which finds the maximum element in an arbitrary binary tree. Assume that every datum in the tree implements Comparable and that no datum is null. /** = the maximum element in the binary tree rooted at t (or null if the tree is empty). Precondition: every datum implements interface Comparable */ public Comparable treeMax(TreeNode t Write the worst-case big-O for the running time of this method given a balanced binary tree containing n nodes, and informally explain your answer. Write the body of method bstMax below, which finds the maximum element in a binary search tree. /** = the max element in BST t (or null if the tree is empty) Precondition: every datum implements interface Comparable */ public Comparable bstMax(TreeNode t Write the big-O for the running time of this method given a balanced BST containing n nodes, and informally explain your answer. Binary tree 7 Recall that the values in any complete binary tree (such as a heap) can be stored in an array according to the following rules (note that this is slightly different than what we did in lecture, where we used index 0): The root is at index 1 Index 0 is unused The left child of a node at i is at 2i The right child of a node at i is at 2i+1 Where is the parent node of a child at i? Write the body for the method below. You may define helper methods if you wish, but any helper method must have a suitable specification. /** = a complete binary tree containing the data stored in b */ TreeNode toTree(Object[] b) Questions on priority queues and heaps PQ and heap 1 In a (binary) heap, for a node at position i, where are its parent, left child and right child located? PQ and heap 2 Given the binary max-heap, 60 / \ / \ 35 45 / \ / / \ / 34 20 19 show what the heap will look like after EACH step of the following sequence of operations: 1. Insert 80 2. Insert 40 3. Remove PQ and heap 3 A priority queue can be implemented using an ordered linked list (descending order) rather than a heap. What are the orders of execution times of the insert and remove operations when an ordered list is used? PQ and heap 4 A priority queue can also be implemented using an unsorted linked list. What are the orders ofworst-case execution time of the insert and remove operations in this case? ? PQ and heap 5 Write a recursive method isHeap() that takes in the root node of a binary tree and returns true if the node is the root of a max-heap and false otherwise. Note that the tree may be empty. The relevant part of the TNode class is shown below: class TNode() { public int value; public TNode left; public TNode right; ... Graph 4 Draw one spanning tree for this graph: } Questions on graphs A Graph 1 (1) Given a directed graph below, write its adjacency matrix and adjacency list. 4 V1 5 7 V3 B V2 3 C 1 6 2 V4 D V5 V6 (2) What is the time complexity of constructing adjacency matrix for a graph with n nodes? Graph 2 Fill in the blanks in the Dijkstra’s shortest path algorithm, given below. The invariant is: (a) For each red node r in R, L[r] is the length of the shortest path from v to r. (b) For each node f in F, L[f] is the length of the shortest path from v to f using only red nodes (except for f) (c) For each node that is not in R or F, L[w] is ∞. (d) Any edge that leaves red set R goes to a node in F. L[w]= _________________ L[v]= 0; F= {v}; while (F not empty) { f= a node in F with min L value; Make f red (delete from F); for each node w adjacent to f: if (L[w] = = ) { ___________________ ___________________ } if (L[f] + weight (f,w) < L[w]) ___________________ } 19 V2 67 V4 V5 41 V -= {A}; E -= {}; //start off with one-node tree s -= _________________ /** invariant:(V,E) is a tree. For all edges (v,w) in s: v is in V and (v,w) Not in E. Any node in graph that is not in V is reacable from the end node of some edge is s. **/ while (s is not empty do) { (v, w) = pop(s); // Take top edge (v,w) off s; if (w is not in V) { _________________ add (v,w) to E; _________________ } } Analysis 1 Put the following in descending order of growth: n, n3, n2, n0, n½, nlog(n), log(n2), n2log(n3), n! 34 15 5 Fill in the blanks in the BFS spanning tree algorithm: Analysis of algorithms questions V1 26 Graph 5 Graph 6 What is the difference between the BFS spanning tree algorithm and the DFS spanning tree algorithm. Graph 3 Write the shortest path from V1 to each node: V3 E V6 Analysis 2 Consider the following java code. Determine its Big-O asymptotic complexity and provide a brief justification. int b[] = new int[N]; int i= 0; while (i < N) { for ( int j= 0;j<5; j= j+1) { b[i]= i+j; i= i+1; } i= i+1; } Analysis 3 Answer the following questions: a. b. c. d. What is a witness pair? Prove that 3n+9 is O(n). Prove that 2n^2 + 3n + 6 is O(n^2) What is the worst case big-Oh of the remove method for a hash table that employs the concept of buckets. Analysis 4 What would happen to the big-oh complexity of MergeSort if instead of dividing the array in two equal length halfs, we divided the array into 3 equal-length sub-arrays at each recursive step? Analysis 5 Determine the Big-O complexity of the following recursive method, assuming a complete binary tree. public int traverse(Node root) { if (root==null) return 0; if (root.left.value > root.value) return traverse(root.left) if(root.right.value > root.value) return traverse(root.right) return root.value; } Analysis 6 Consider the following iterative code. Determine its Big-Oh: Let N= a + b. int b[][]= new int[a][b]; for (int i= 0; i < b; i= i+1) { int j= 0; while (j < a) { b[j][i]= i+j; j++, i++; } } Analysis 6 Explain why the in best case, insertion sort is O(N). SAMPLE ANSWERS Interface and class 1 Suppose class C could extend both C1 and C2, and that there were methods C1.m() and C2.m(). Which one should C inherit? If one inherits both, what does a call m() in C do? These sorts of questions have never been answered satisfactorily, so Java outlaws multiple inheritance so these questions don’t arise. Interface and class 2 If the classes compile, then any method defined in Coin must also be defined in Nickel and Quarter. The only two methods defined in both are getValue() and getYear(), so the answer is 2, and these are the two methods. Interface and class 3 A static method may not refer to a nonstatic field. Interface and class 4 (a) Boat b= new Boat(); Legal (b) WaterCraft wc= (WaterCraft) b; Legal (c) Vehicle v= (Vehicle) wc; Illegal (d) MotorVehicle mv= (MotorVehicle) b; Legal (e) MotorVehicle mv2= (MotorVehicle) wc; Illegal Interface and class 5 Remember, a nested class is a static class that is placed inside another class. Get it out of the way; make it private so others can’t refer to it directly. Interface and class 6 (2) You don’t want the reader to have to deal with it; user should not see it. (3) Reduce the number of files one has to deal with. (4) Methods in class I have to refer to fields of class O in which it is placed (so it can’t be a nested class (i.e. a static class). Placing class I within class O simplifies referring to these fields. Interface and class 7 It is an inner class because it is non-static. Also nested classes cannot access member variables of the outer class (and in this case it does). Interface and class 7 // not a circular linked list if( p == null) return 0; // otherwise looped through entire list return count; } Linked list 3 /** = l1 is sorted. l2 is sorted. Return a sorted links list that with all their elements */ public LinkedList merge(LinkedList l1, LinkedList l2){ if (l1 == null && l2 == null) return null; Questions on linked lists Linked list 1 Keep two pointers that march down the list at different speeds 1 and 2. If they become equal, there is a cycle // = “head has a cycle” public boolean isCyclic(LinkedList head) { if (head == null) return false; // p advances 2 nodes per iteration // tp advances 1 node per iteration LinkedList p, head.next; LinkedList tp = head; while (p != null && p != tp) { tp= tp.next; p= p.next; if (p == null) return false; p= p.next; } // { p is null or p = tp } if (p == null) return false; return true; } Linked list 2 /** = number of nodes in circular list head */ public int numNodes(LinkedList head) { if ( head == null) return 0; LinkedList p= head.next; int count= 1; // invariant: p is a node in the list // c is the number of nodes before it // if p = head, that means c is no of nodes in list while (p != head) { p= p.next; count= count + 1; } LinkedList head= new LinkedList(); LinkedList lc1= l1; LinkedList lc2= l2; LinkedList cursor= head; /** invariant: lc1 and lc2 are names of nodes in the two lists l1 and l2 (null if the lists have been completely copied). There is an empty node at beginning of head, To be removed at the end. All the nodes before lc1 and lc2 appear in list head, and cursor is the last node in list head (null if head is null). All the values in list head are no bigger than those in lc1 and lc2 while (lc1 != null && lc2 != null) { cursor.next = new LinkedList(); cursor = cursor.next; cursor.next = null; if (lc1.data < lc2.data) { cursor.data= lc1.data; lc1= lc1.next; } else { cursor.data= lc2.data; lc2= lc2.next; } } // Set lc1 to the one of lc1 and lc2 that is not null if (lc2 != null) lc1= lc2; // Copy the rest of list lc21 (if any) while (lc1 != null) { cursor.next= new LinkedList(); cursor= cursor.next; cursor.next= null; cursor.data= lc1.data; lcc1= lc1.next; } // { head contains an empty node followed by all the values in l1 and l2, in sorted order } return head.next; TreeNode tCopy= new TreeNode(); tCopy.datum= fn.translate(t.datum); tCopy.left= treeTrans(fn, t.left); tCopy.right= treeTrans(fn, t.right); return tCopy; } Linked list 4 /** = a linked list consisting of l1 nodes followed by l2’s nodes */ public LinkedList append(LinkedList l1, LinkedList l2) { LinkedList l3= new LinkedList(); LinkedList lc3= null; LinkedList lc= l1; } Binary tree 3 Preorder: Postorder: Inorder: 6 / \ 3 7 / \ \ 1 5 9 / \ 4 10 /** inv: l3 contains an empty node followed by the nodes in list l1 up to but not including node lc. The last node in l3 is lc3 */ while (lc1!= null) { lc3.next= new LinkedList(); lc3 = lc3.next; lc3.data = lc.data; lc = lc1.next; } lc= l2; /** inv: l3 contains an empty node followed by the nodes in list l1 followed by the nodes in l2 up to but not including node lc. The last node in l3 is lc3 */ while (lc1!= null) { lc3.next= new LinkedList(); lc3 = lc3.next; lc3.data = lc.data; lc = lc1.next; } return l3.next; } Questions on binary trees: Binary tree 1. // = “the tree rooted at a is a mirror image of the tree rooted at b” public static boolean isMirror(TreeNode a, TreeNode b) { if (a==null && b==null) return true; if (a==null || b==null) return false; if (!a.datum.equals(b.datum)) return false; return isMirror(a.left,b.right) && isMirror(a.right,b.left); } Binary tree 2 /** = a new binary tree that has the same shape as t but with each datum replaced with the result of calling fn.translate() */ TreeNode treeTrans(Translator fn, TreeNode t) { if (t==null) return; 6, 3, 1, 5, 7, 9 1, 5, 3, 9, 7, 6 1, 3, 5, 6, 7, 9 5 / \ 3 7 / \ 1 9 or 7 / \ 3 9 / \ 1 5 No. One of the values in the left subtree of the root (8) is not less than the value at the root (7). Binary tree 4 // Print out all the data in the tree in preorder public void printNTree(NTreeNode t) { if (t==null) return; System.out.println(t.datum); NTreeNode child= t.firstChild; while (child!=null) { printNTree(child); child= child.nextSibling; } } // = the number of levels in the tree // (a tree with 0 nodes has 0 levels) public int ntreeHeight(NTreeNode t) { if (t==null) return 0; int maxHt= 0; int curHt; NTreeNode child= t.firstChild; while (child!=null) { curHt = ntreeHeight(child); if (curHt > maxHt) maxHt= curHt; child= child.nextSibling; return bstMax(t.right); } } // add the current level to tallest subtree O(log n). The algorithm traverses one path from the root to the rightmost node in the BST. The length of this path is the height of the tree, which is log n for any balanced tree of n nodes. return maxHt + 1; } Binary tree 5 // = “the heap contains the target value” // Precondition: t is the root of a min- or max-heap public bool isInHeap(TreeNode t, Object target) { if (t==null) return false; if (t.datum.equals(target)) return true; return isInHeap(t.left,target) || isInHeap(t.right,target); } Binary tree 7 O(n). In the worst case, the target value is not in the tree and we examine every node in the heap looking for this value. /** = a complete binary tree containing representing the tree rooted at i (or null if i is outside the bounds of b) */ TreeNode toTreeHelper(Object[] b, int i) { if (i>=b.length) return null; O(log n). To search in a BST, walk down just one path from the root of the tree to a leaf. That is, at each node, we look down only the branch that could contain the target value and ignore the other branch. In the worst case, target is not present, and the path from root to leaf is walked. In a balanced tree of n nodes, the height of the tree (the length of this path) is log n. Binary tree 6 /** = the maximum element in binary tree rooted t (or null if t is empty). Precondition: every datum implements interface Comparable */ public Comparable treeMax(TreeNode t) { if (t==null) return null; Comparable current= (Comparable)t.datum; Comparable m= treeMax(r.left); if (m != null && m.compareTo(current) > 0) current= ; m= treeMax(r.right); if (m != null && m.compareTo(current) > 0) current= m; At i/2 (using Java integer division, which always rounds down) /** = a complete binary tree containing the data stored in b */ TreeNode toTree(Object[] b) { return toTreeHelper(b, 1); } TreeNode current= new TreeNode(); current.datum= b[i]; current.left= toTreeHelper(b, 2*i); current.right= toTreeHelper(b, 2*i + 1); return current; } PQ and heap 1 In a heap, we number the nodes left-right breadthfirst. If we start with 0, the root is at 0, its left child is at 1, right child is at 2 and so on. For a node at position i, its parent is at: FLOOR((i-1)/2), left child is at: 2i+1, and right child is at: 2i+2. The only exception is the root node, which does not have a parent. Some authors start numbering at 1. This means that if the heap is stored in an array, array element 0 is unused, and the formulas are slightly different. PQ and heap 2 80 / \ return current; } O(n). In an arbitrary tree, any value could be anywhere, so we much examine every node in the tree to find the maximum. / \ 35 60 / \ / \ / \ / \ 34 20 19 45 /** = maximum element in BST t (or null if t is empty) Precondition: every datum implements interface Comparable */ Public Comparable bstMax(TreeNode t) { if (t==null) return null; if (t.right==null) return (Comparable)t.datum; 80 / \ / 40 / \ / \ \ 60 / \ / \ 35 / / 34 20 19 45 12 3null 25null 345null 4null 56null 61null 60 / \ / \ 40 45 / \ / \ / \ / \ 35 20 19 34 Graph 2 PQ and heap 3 Insert: O(n) - worst case, the new node goes at the end of the list Remove: O(1) - the maximum value is always at the root. PQ and heap 4 Insert: O(1) - always insert the new node at the head Remove: O(n) – in the worst case, the maximum value is at the end of the list PQ and heap 5 /** = “t is a max-heap” public static boolean isHeap(TNode t) { // no nude is good news if (t==null) return true; L[w]= for all nodes L[v]= 0; F= {v}; while (F not empty) { f= a node in F with min L value; Make f red (delete from F); for each node w adjacent to f: if (L[w] = = ) { L[w]= L[f] + weight(f,w); Put w in F; } else if (L[f] + weight (f,w) < L[w]) L[w]= L[f] + weight(f,w); } Graph 3 // return false if right node exists but left node doesn’t if (t.left == null && t.right != null) return false; // return false if either child is smaller than node t if (t.left != null && t.value < t.left.value) return false; if (t.right != null && t.value < t.right.value) return false; // { children, if the exist, are smaller } return isHeap(t.left) && isHeap(t.right); The shortest paths from V1 to all nodes in this graph are: 2 3 4 5 6 12 13 134 135 1356 Graph 4 Here is one spanning tree of the graph: } A 4 Graph questions Graph 1 B Adjacency Matrix: 1 2 3 4 5 6 1 f f f f f t Adjacency List: 2 t f f f f f 3 t f f f f f 4 f f t f f f 5 f t t f f f 6 f f f f t f C 3 1 D 2 E Graph 4 The filled BFS spanning tree algorithm is: V = {A}; E = {}; //start off with one-node tree s = queue of edges to neighbors of A; /** invariant:(V,E) is a tree. For all edges (v,w) in s: v is in V and (v,w) not in E. Any node in graph that is not in V is reachable from the end node of some edge is s. **/ while (s is not empty do) { (v, w) = pop(s); // Take top edge (v,w) off s; if (w is not in V) { Add w to V; add (v,w) to E; Push onto s all edges with start node w; } } Graph 4 The BFS spanning tree algorithm uses a queue to store edges. The DFS spanning tree algorithm uses a stack to store edges, Analysis of algorithms questions Analysis 1 n!, n3, n2log(n3), n2, nlog(n), n, n½, log(n2), n0 Notes: n^0 = 1, log(n^2) = 2log n = O(log n), n^2log(n^3) = 3n^2log(n) = O(n^2 log n) Analysis 2 O(N). Despite the nested loop structure, each of the N elements in array b is processed only once. Analysis 3 e. What is a witness pair? In proving that f(n) is O(g(n), one must find c>0 and N0 > 0 such that f(n) <= c*g(n) for all n > N0. The witness pair is (c,N0). f. Prove that 3n+9 is O(n). The witness pair (c, No) = (4,9) does the trick. g. Prove that 2n^2 + 3n + 6 is O(n^2) The witness pair (c, No) = (4,3) does the trick. h. O(N) Analysis 4 Normally, MergeSort divides the array into two equal halfs and recurses on them. Hence, because of this halving effect, the depth of recursion is log N. However, at each depth, all N objects of the array are visited, so the complexity is N log N. We can apply similar informal logic in this case. We know that because of the three way split, the depth of recursion is going to be log3N (instead of log2N. At each depth, all N nodes will be visited. Hence, the complexity is O(N log3N), which we know is O(N log N) [Provable by a witness pair argument, definition of Big-Oh]. Analysis 5 O(log N) (where N is the number of nodes in the tree) because traverses each node on only one path down to the leaf nodes and the tree is complete, so its depth is log(N) Analysis 6 O(N) Analysis 6 The best case for insertion sort is when the array is already sorted in ascending order. Then, at each iteration, the algorithm make only one comparison, determining that the current item is already in its place. Hence, there would be a total of N comparisons (and no array-element swaps), one for each of the N elements in the array.