Date: Wed, 27 Oct 1999 11:20:55 -0400 (EDT) From: Archisman RudraSubject: HW3 Soln-s Sample Solution to HW3 : Archi 1. Let m be the input size on the new machine. Then, because both machines take the same time T, T = T(n) and T = (1/64) T(m) i.e. T(m) = 64 * T(n) We solve this in the various cases: (a) T(n) = 3 * 2^n. i.e., 3 * 2^m = 64 * 3 * 2^n or, 2^m = 64 * 2^n or, m = n + 6 (after taking lg) (b) T(n) = n^2. ie, m^2 = 64 * n^2, or, m = 8 * n (Taking square roots) (c) T(n) = 8 * n. ie, 8 * m = 64 * 8 * n or m = 64 * n 2. To show that log (n!) = Theta (n log n) (a) log (n!) = log 1 + log 2 + ... + log n <= log n + log n + ... + log n (n terms) = n log n. This shows that log (n!) = O (n log n) (b) log (n!) = log 1 + log 2 + ... + log n >= log (n/2) + log (n/2 + 1) + ... + log n (about (n/2) terms) >= log (n/2) + log (n/2) + ... + log (n/2) (n/2 terms (about)) = (n/2) log (n/2) We will show that (n/2) log (n/2) >= (1/4) n log n, for n >= 4 (n/2) log (n/2) = (1/2) n log n - (1/2) n n >= 4 = 2^2 => log n >= 2 => n * log n >= 2 * n (since n >= 4 > 0) => (1/4) n log n >= (1/2) n => -(1/2) n >= -(1/4) n * log n => (1/2) n * log n - (1/2) n >= (1/2) n * log n - (1/4) n * log n = (1/4) n * log n. i.e, log (n!) >= (n/2) log (n/2) >= (1/4) n * log n, for n >= 4. From (a) and (b), we conclude log (n!) = Omega (n * log n) 3. (a) 9 9 9 etc.: Final tree: 9 / / / \ 7 7 7 12 / / \ / \ 2 2 8 10 16 / \ \ / 1 5 11 13 (b) 9 7 2 1 5 8 12 10 11 16 13 (c) 1 2 5 7 8 9 10 11 12 13 16 (d) 1 5 2 8 7 11 10 13 16 12 9 (e) 9 / \ 7 13 / \ / \ 2 8 10 16 / \ \ 1 5 11 assuming we use the immediate successor rule. 4. Initial Array: 9, 7, 2, 8, 12, 5, 1, 16, 10, 13. 11 (No need to write this) The initial config is: 9 / \ 7 2 / \ / \ 8 12 5 1 / \ / \ 16 10 13 11 After 3 siftdowns: 9 / \ 7 5 / \ / \ 16 13 2 1 / \ / \ 8 10 12 11 One more siftdown: 9 / \ 16 5 / \ / \ 10 13 2 1 / \ / \ 8 7 12 11 Final tree: 16 / \ 13 5 / \ / \ 10 12 2 1 / \ / \ 8 7 9 11 (b) RemoveMax removes the maximum element (16). 11 / \ 13 5 / \ / \ 10 12 2 1 / \ / 8 7 9 And after siftdown to rebuild the heap: 13 / \ 12 5 / \ / \ 10 11 2 1 / \ / 8 7 9 5. Programming part: /* file: myNode.java * Basic Algorithms, Fall 1999, Yap * * HW3 problem: * It declares an interface called "nodeInt" * and a class myNode that implements nodeInt. * The interface nodeInt is a variation taken from hw2. * */ import java.io.*; // to use DataInputStream //================================================== // nodeInt: // this interface is a slight variation of what // you did for hw2. In particular, we now assume // "item" is a String rather than a general object. // // For comparisons, you use "S1.compareTo(S2)" as // explained under "merge" below. //================================================== interface nodeInt { //================================================== // basic methods (as in hw2) //================================================== public void setItem(String i); public void setNext(nodeInt n); // next = n public nodeInt getNext(); public String getItem(); public void printItem(); public void print(); //================================================== // methods for File I/O (as in hw2) //================================================== public int readString(DataInputStream dis); // NOTE: on Unix/Linux, end-of-line is indicated by "\n" // On Windows, end-of-line is indicated by "\r\n". public int readFromFile(String fn); } // nodeInt public class myNode implements nodeInt { //================================================== // variables //================================================== private String item; private nodeInt next; //================================================== // constructors //================================================== myNode() {// fill in your code; this(null, null); } myNode(String e, nodeInt n) {// fill in your code; item = e; next = n; } //================================================== // basic methods // -- remove "abstract" and fill in code //================================================== public void setItem(String i) { item = i; } // public abstract void setItem(nodeInt n); public void setNext(nodeInt n) { next = n; } public nodeInt getNext() { return next;} public String getItem() { return item; } public void printItem() { System.out.print(item); } public void print() { myNode pointer = this; while (pointer != null) { pointer.printItem(); System.out.print("\n"); pointer = (myNode) pointer.getNext(); } } public int readString(DataInputStream dis) { byte[] cc = new byte[100]; byte c; boolean EOF_FLAG = false; int i = 0; try{ while( !EOF_FLAG ) { c = dis.readByte(); if (c == '\n') { EOF_FLAG = true; // dis.readByte(); // following '\r' is '\n', } // which we just discard else { cc[i] = c; i++; } } } catch(Exception e) { item = null; return -1; }; item = new String(cc, 0, i); return i; } //readString public int readFromFile(String fn) // returns the number of nodes in list // the first node in the read-in list is "this" // if the returned value is <0, error in opening files { FileInputStream is = null; DataInputStream dis = null; try { is = new FileInputStream(fn); dis = new DataInputStream(is); } catch (Exception e) { System.out.println("Fail to Open"); return -1; } int count = 0; myNode curr = new myNode(); myNode last = this; if (curr.readString(dis) < 0) { return -1; } else { ++count; last.setItem(curr.getItem()); curr = new myNode(); while (curr.readString(dis) >= 0) // allow 0 length item { last.setNext(curr); last = (myNode) last.getNext(); curr = new myNode(); ++count; } } return count; } //readFromFile //================================================== // sort: // implements merge sort of a list of strings // in increasing order. // Returns the nodeInt that is the start of the // sorted list. //================================================== public nodeInt sort() {myNode even, odd; if(this == null) return null; if(this.getNext() == null) return this; even = (myNode) split (); odd = this; return merge (even.sort(), odd.sort()); } //================================================== // split: // takes *this* list, and splits it into // an odd sublist and an even sublists. // The value of *this* is the first node in the odd // and the returned value is the first node of the // even sublist. [Note: the even sublist has length // equal to, or one less than, the length of odd sublist.] // // Assume *this* has at least one node. // CAREFUL: the input list must be NULL terminated. //================================================== public nodeInt split() { nodeInt oddPointer, evenPointer, retVal, temPtr; boolean done; if (this == null) return null; oddPointer = this; retVal = evenPointer = this.getNext(); done = false; while (!done) { if (evenPointer != null){ temPtr = evenPointer.getNext(); oddPointer.setNext(temPtr); oddPointer = temPtr; } else { done = true; continue; } if (oddPointer != null){ temPtr = oddPointer.getNext(); evenPointer.setNext(temPtr); evenPointer = temPtr; } else done = true; } return retVal; } //================================================== // merge(L, L1) // -- assumes L and L1 not null // -- returns the first node of the merged list. // -- To compare, you will need to use the "compareTo" // method for Strings. E.g. // // String s1 = "111"; // String s2 = "222"; // if (s1.compareTo(s2) < 0) // System.out.println("s1 is smaller than s2"); // else // System.out.println("s1 is not smaller than s2"); // // -- In fact, (s1.compareTo(s2) == 0) if and only if // the two strings are equal. //================================================== public static myNode merge(nodeInt L, nodeInt L1) { myNode l, l1; // dummy implementation ! if (L == null) return (myNode)L1; if (L1 == null) return (myNode) L; l1 = (myNode) L1; l = (myNode) L; if(l.item.compareTo(l1.item) < 0){ L.setNext( merge (L.getNext(), L1)); return (myNode) L; } else { L1.setNext( merge (L, L1.getNext())); return (myNode) L1; } }; //================================================== public static void main(String[] args) { /* THIS IS THE REQUIRED BODY:*/ String fn = "input.0"; // default file if (args.length > 0) fn = args[0]; // if file is specified myNode N = new myNode(); int n = N.readFromFile(fn); // create a list from file "fn" System.out.println("....INPUT LIST:"); N.print(); N = (myNode)N.sort(); System.out.println("....SORTED LIST:"); N.print(); } } //Node class