├── .gitattributes ├── .gitignore ├── hw ├── hw1 │ ├── Nuke2.java │ └── OpenCommercial.java ├── hw10 │ └── sort │ │ └── Sorts.java ├── hw2 │ └── Date.java ├── hw3 │ ├── Homework3.java │ ├── SList.java │ ├── SListNode.java │ └── TestHelper.java ├── hw4 │ └── list │ │ ├── DList.java │ │ ├── DListNode.java │ │ ├── LockDList.java │ │ ├── LockDListNode.java │ │ ├── TestDList.java │ │ ├── TestHelper.java │ │ └── TestLockDList.java ├── hw5 │ ├── Set.java │ └── list │ │ ├── DList.java │ │ ├── DListNode.java │ │ ├── InvalidNodeException.java │ │ ├── List.java │ │ ├── ListNode.java │ │ ├── SList.java │ │ └── SListNode.java ├── hw6 │ ├── Homework6Test.java │ ├── SimpleBoard.java │ ├── dict │ │ ├── Dictionary.java │ │ ├── Entry.java │ │ └── HashTableChained.java │ └── list │ │ ├── SList.java │ │ └── SListNode.java ├── hw7 │ └── dict │ │ ├── IntDictionary.java │ │ ├── Tree234.java │ │ └── Tree234Node.java ├── hw8 │ ├── ListSorts.java │ ├── Timer.java │ └── list │ │ ├── LinkedQueue.java │ │ ├── Queue.java │ │ ├── QueueEmptyException.java │ │ └── SListNode.java └── hw9 │ ├── Maze.java │ └── set │ └── DisjointSets.java ├── lab ├── lab1 │ └── Names.java ├── lab10 │ └── tree │ │ ├── InvalidNodeException.java │ │ ├── SibTree.java │ │ ├── SibTreeNode.java │ │ ├── Tree.java │ │ └── TreeNode.java ├── lab11 │ └── dict │ │ ├── BinaryTree.java │ │ ├── BinaryTreeNode.java │ │ ├── Dictionary.java │ │ └── Entry.java ├── lab12 │ ├── Sort.java │ ├── SortPerf.java │ ├── Timer.java │ └── YourSort.java ├── lab13 │ ├── UDGraph.class │ └── UDGraph.java ├── lab14 │ └── dict │ │ ├── BinaryTreeNode.java │ │ ├── Dictionary.java │ │ ├── Entry.java │ │ └── SplayTree.java ├── lab15 │ └── GimmeYoNumber.java ├── lab2 │ └── Fraction.java ├── lab3 │ ├── SList.java │ ├── SListNode.java │ └── TestHelper.java ├── lab4 │ ├── DList1.java │ ├── DList2.java │ ├── DListNode1.java │ └── DListNode2.java ├── lab6 │ ├── AccountData.java │ ├── BadAccountException.java │ ├── BadTransactionException.java │ ├── BankApp.java │ ├── VirtualTeller.java │ └── sortedlist │ │ ├── Keyable.java │ │ ├── ListEnum.java │ │ ├── ListNode.java │ │ └── SortedList.java └── lab7 │ ├── DebugMe.java │ └── ListNode.java ├── pj1 ├── Blur.java ├── DList.java ├── DListNode.java ├── ImageUtils.java ├── PixImage.java ├── RunIterator.java ├── RunLengthEncoding.java ├── Sobel.java ├── TIFF6.pdf ├── TIFFEncoder.java ├── Test.java ├── baby.tiff ├── black.tiff ├── data.gz ├── engine.tiff ├── feathers.tiff ├── flower.tiff ├── highcontrast.tiff ├── jai_codec.jar ├── jai_core.jar ├── readme.pdf ├── reggie.tiff └── woman.tiff └── pj3 ├── KruskalTest.java ├── WUGTest.java ├── graph ├── Neighbors.java ├── VertexPair.java └── WUGraph.java ├── graphalg └── Kruskal.java ├── pj3graph.pdf ├── readme.pdf └── set └── DisjointSets.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /hw/hw1/Nuke2.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class Nuke2 { 4 | 5 | public static void main(String[] arg) throws Exception{ 6 | 7 | BufferedReader keyboard; 8 | String inputLine; 9 | 10 | keyboard = new BufferedReader(new InputStreamReader(System.in)); 11 | inputLine = keyboard.readLine(); 12 | 13 | String out; 14 | out = inputLine.charAt(0)+inputLine.substring(2); 15 | System.out.println(out); 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /hw/hw1/OpenCommercial.java: -------------------------------------------------------------------------------- 1 | /* OpenCommercial.java */ 2 | 3 | import java.net.*; 4 | import java.io.*; 5 | 6 | /** A class that provides a main function to read five lines of a commercial 7 | * Web page and print them in reverse order, given the name of a company. 8 | */ 9 | 10 | class OpenCommercial { 11 | 12 | /** Prompts the user for the name X of a company (a single string), opens 13 | * the Web site corresponding to www.X.com, and prints the first five lines 14 | * of the Web page in reverse order. 15 | * @param arg is not used. 16 | * @exception Exception thrown if there are any problems parsing the 17 | * user's input or opening the connection. 18 | */ 19 | public static void main(String[] arg) throws Exception { 20 | 21 | BufferedReader keyboard; 22 | String inputLine; 23 | 24 | keyboard = new BufferedReader(new InputStreamReader(System.in)); 25 | 26 | System.out.print("Please enter the name of a company (without spaces): "); 27 | System.out.flush(); /* Make sure the line is printed immediately. */ 28 | inputLine = keyboard.readLine(); 29 | 30 | /* Replace this comment with your solution. */ 31 | String url = "http://www."+inputLine+".com"; 32 | URL u = new URL(url); 33 | InputStream ins = u.openStream(); 34 | InputStreamReader isr = new InputStreamReader(ins); 35 | BufferedReader w = new BufferedReader(isr); 36 | String[] out = new String[5]; 37 | for(int i=0; i<5; i++) 38 | { 39 | out[i] = w.readLine(); 40 | } 41 | for(int i=4; i>=0; i--) 42 | { 43 | System.out.println(out[i]); 44 | } 45 | 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /hw/hw10/sort/Sorts.java: -------------------------------------------------------------------------------- 1 | /* Sorts.java */ 2 | 3 | package sort; 4 | 5 | public class Sorts { 6 | 7 | /** 8 | * Place any final static fields you would like to have here. 9 | **/ 10 | 11 | 12 | /** 13 | * countingSort() sorts an array of int keys according to the 14 | * values of _one_ of the base-16 digits of each key. "whichDigit" 15 | * indicates which digit is the sort key. A zero means sort on the least 16 | * significant (ones) digit; a one means sort on the second least 17 | * significant (sixteens) digit; and so on, up to a seven, which means 18 | * sort on the most significant digit. 19 | * @param key is an array of ints. Assume no key is negative. 20 | * @param whichDigit is a number in 0...7 specifying which base-16 digit 21 | * is the sort key. 22 | * @return an array of type int, having the same length as "keys" 23 | * and containing the same keys sorted according to the chosen digit. 24 | * 25 | * Note: Return a _newly_ created array. DO NOT CHANGE THE ARRAY keys. 26 | **/ 27 | public static int[] countingSort(int[] keys, int whichDigit) { 28 | // Replace the following line with your solution. 29 | int[] output = new int[keys.length]; 30 | int[] afterBit = new int[keys.length]; 31 | int[] counts = new int[16]; 32 | int total, c; 33 | 34 | for(int i = 0; i < keys.length; i++){ 35 | afterBit[i] = (keys[i] >> (whichDigit*4)) & 15; 36 | } 37 | 38 | for(int i = 0; i < keys.length; i++){ 39 | counts[afterBit[i]]++; 40 | } 41 | 42 | total = 0; 43 | for(int i = 0; i < counts.length; i++){ 44 | c = counts[i]; 45 | counts[i] = total; 46 | total += c; 47 | } 48 | 49 | for(int i = 0; i < keys.length; i++){ 50 | output[counts[afterBit[i]]] = keys[i]; 51 | counts[afterBit[i]]++; 52 | } 53 | return output; 54 | } 55 | 56 | /** 57 | * radixSort() sorts an array of int keys (using all 32 bits 58 | * of each key to determine the ordering). 59 | * @param key is an array of ints. Assume no key is negative. 60 | * @return an array of type int, having the same length as "keys" 61 | * and containing the same keys in sorted order. 62 | * 63 | * Note: Return a _newly_ created array. DO NOT CHANGE THE ARRAY keys. 64 | **/ 65 | public static int[] radixSort(int[] keys) { 66 | // Replace the following line with your solution. 67 | int[] sort = new int[keys.length]; 68 | sort = keys; 69 | for(int i = 0; i <= 7; i++){ 70 | sort = countingSort(sort, i); 71 | } 72 | return sort; 73 | } 74 | 75 | /** 76 | * yell() prints an array of int keys. Each key is printed in hexadecimal 77 | * (base 16). 78 | * @param key is an array of ints. 79 | **/ 80 | public static void yell(int[] keys) { 81 | System.out.print("keys are [ "); 82 | for (int i = 0; i < keys.length; i++) { 83 | System.out.print(Integer.toString(keys[i], 16) + " "); 84 | } 85 | System.out.println("]"); 86 | } 87 | 88 | /** 89 | * main() creates and sorts a sample array. 90 | * We recommend you add more tests of your own. 91 | * Your test code will not be graded. 92 | **/ 93 | public static void main(String[] args) { 94 | int[] keys = { Integer.parseInt("60013879", 16), 95 | Integer.parseInt("11111119", 16), 96 | Integer.parseInt("2c735010", 16), 97 | Integer.parseInt("2c732010", 16), 98 | Integer.parseInt("7fffffff", 16), 99 | Integer.parseInt("4001387c", 16), 100 | Integer.parseInt("10111119", 16), 101 | Integer.parseInt("529a7385", 16), 102 | Integer.parseInt("1e635010", 16), 103 | Integer.parseInt("28905879", 16), 104 | Integer.parseInt("00011119", 16), 105 | Integer.parseInt("00000000", 16), 106 | Integer.parseInt("7c725010", 16), 107 | Integer.parseInt("1e630010", 16), 108 | Integer.parseInt("111111e5", 16), 109 | Integer.parseInt("61feed0c", 16), 110 | Integer.parseInt("3bba7387", 16), 111 | Integer.parseInt("52953fdb", 16), 112 | Integer.parseInt("40013879", 16) }; 113 | 114 | yell(keys); 115 | keys = radixSort(keys); 116 | yell(keys); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /hw/hw2/Date.java: -------------------------------------------------------------------------------- 1 | /* Date.java */ 2 | 3 | import java.io.*; 4 | 5 | class Date { 6 | private int month; 7 | private int day; 8 | private int year; 9 | 10 | /* Put your private data fields here. */ 11 | private int dayInAll(){ 12 | int days = 0; 13 | int leapYearCount = 0 ; 14 | for(int i = 1; i < year; i++){ 15 | if(isLeapYear(i)) leapYearCount++; 16 | } 17 | days = (year - 1) * 365 + leapYearCount +dayInYear(); 18 | return days; 19 | } 20 | 21 | /** Constructs a date with the given month, day and year. If the date is 22 | * not valid, the entire program will halt with an error message. 23 | * @param month is a month, numbered in the range 1...12. 24 | * @param day is between 1 and the number of days in the given month. 25 | * @param year is the year in question, with no digits omitted. 26 | */ 27 | public Date(int month, int day, int year) { 28 | if(!isValidDate(month, day, year)) { 29 | System.exit(0); 30 | }else{ 31 | this.month = month; 32 | this.day = day; 33 | this.year = year; 34 | } 35 | } 36 | 37 | /** Constructs a Date object corresponding to the given string. 38 | * @param s should be a string of the form "month/day/year" where month must 39 | * be one or two digits, day must be one or two digits, and year must be 40 | * between 1 and 4 digits. If s does not match these requirements or is not 41 | * a valid date, the program halts with an error message. 42 | */ 43 | public Date(String s) { 44 | String[] fields = s.split("/"); 45 | if(fields.length != 3){ 46 | System.exit(0); 47 | } 48 | month = Integer.parseInt(fields[0]); 49 | day = Integer.parseInt(fields[1]); 50 | year = Integer.parseInt(fields[2]); 51 | if(!isValidDate(month, day, year)) System.exit(0); 52 | } 53 | 54 | /** Checks whether the given year is a leap year. 55 | * @return true if and only if the input year is a leap year. 56 | */ 57 | public static boolean isLeapYear(int year) { 58 | if((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0)) 59 | return true; 60 | else 61 | return false; 62 | } 63 | 64 | /** Returns the number of days in a given month. 65 | * @param month is a month, numbered in the range 1...12. 66 | * @param year is the year in question, with no digits omitted. 67 | * @return the number of days in the given month. 68 | */ 69 | public static int daysInMonth(int month, int year) { 70 | switch(month){ 71 | case 2: if(isLeapYear(year)) return 29; 72 | else return 28; 73 | case 4: 74 | case 6: 75 | case 9: 76 | case 11: return 30; 77 | default: return 31; 78 | } 79 | 80 | } 81 | 82 | /** Checks whether the given date is valid. 83 | * @return true if and only if month/day/year constitute a valid date. 84 | * 85 | * Years prior to A.D. 1 are NOT valid. 86 | */ 87 | public static boolean isValidDate(int month, int day, int year) { 88 | if(month < 1 || month > 12) return false; 89 | if(day < 1 || day >daysInMonth(month, year)) return false; 90 | if(month == 2 && day == 29 && !isLeapYear(year)) return false; 91 | return true; 92 | } 93 | 94 | /** Returns a string representation of this date in the form month/day/year. 95 | * The month, day, and year are expressed in full as integers; for example, 96 | * 12/7/2006 or 3/21/407. 97 | * @return a String representation of this date. 98 | */ 99 | public String toString() { 100 | return String.valueOf(month) + "/" + String.valueOf(day) + "/" + String.valueOf(year); // replace this line with your solution 101 | 102 | } 103 | 104 | /** Determines whether this Date is before the Date d. 105 | * @return true if and only if this Date is before d. 106 | */ 107 | public boolean isBefore(Date d) { 108 | return this.dayInAll() - d.dayInAll() < 0; // replace this line with your solution 109 | } 110 | 111 | /** Determines whether this Date is after the Date d. 112 | * @return true if and only if this Date is after d. 113 | */ 114 | public boolean isAfter(Date d) { 115 | return this.dayInAll() - d.dayInAll() > 0; // replace this line with your solution 116 | } 117 | 118 | /** Returns the number of this Date in the year. 119 | * @return a number n in the range 1...366, inclusive, such that this Date 120 | * is the nth day of its year. (366 is used only for December 31 in a leap 121 | * year.) 122 | */ 123 | public int dayInYear() { 124 | if(month == 1){ 125 | return day; 126 | }else{ 127 | int days = 0; 128 | for(int i=1; i < month; i++){ 129 | days = days + daysInMonth(i, year); 130 | } 131 | days = days + day; 132 | return days; 133 | } 134 | } 135 | 136 | /** Determines the difference in days between d and this Date. For example, 137 | * if this Date is 12/15/2012 and d is 12/14/2012, the difference is 1. 138 | * If this Date occurs before d, the result is negative. 139 | * @return the difference in days between d and this date. 140 | */ 141 | public int difference(Date d) { 142 | return this.dayInAll() - d.dayInAll(); // replace this line with your solution 143 | } 144 | 145 | public static void main(String[] argv) { 146 | System.out.println("\nTesting constructors."); 147 | Date d1 = new Date(1, 1, 1); 148 | System.out.println("Date should be 1/1/1: " + d1); 149 | d1 = new Date("2/4/2"); 150 | System.out.println("Date should be 2/4/2: " + d1); 151 | d1 = new Date("2/29/2000"); 152 | System.out.println("Date should be 2/29/2000: " + d1); 153 | d1 = new Date("2/29/1904"); 154 | System.out.println("Date should be 2/29/1904: " + d1); 155 | 156 | d1 = new Date(12, 31, 1975); 157 | System.out.println("Date should be 12/31/1975: " + d1); 158 | Date d2 = new Date("1/1/1976"); 159 | System.out.println("Date should be 1/1/1976: " + d2); 160 | Date d3 = new Date("1/2/1976"); 161 | System.out.println("Date should be 1/2/1976: " + d3); 162 | 163 | Date d4 = new Date("2/27/1977"); 164 | Date d5 = new Date("8/31/2110"); 165 | 166 | /* I recommend you write code to test the isLeapYear function! */ 167 | 168 | System.out.println("\nTesting before and after."); 169 | System.out.println(d2 + " after " + d1 + " should be true: " + 170 | d2.isAfter(d1)); 171 | System.out.println(d3 + " after " + d2 + " should be true: " + 172 | d3.isAfter(d2)); 173 | System.out.println(d1 + " after " + d1 + " should be false: " + 174 | d1.isAfter(d1)); 175 | System.out.println(d1 + " after " + d2 + " should be false: " + 176 | d1.isAfter(d2)); 177 | System.out.println(d2 + " after " + d3 + " should be false: " + 178 | d2.isAfter(d3)); 179 | 180 | System.out.println(d1 + " before " + d2 + " should be true: " + 181 | d1.isBefore(d2)); 182 | System.out.println(d2 + " before " + d3 + " should be true: " + 183 | d2.isBefore(d3)); 184 | System.out.println(d1 + " before " + d1 + " should be false: " + 185 | d1.isBefore(d1)); 186 | System.out.println(d2 + " before " + d1 + " should be false: " + 187 | d2.isBefore(d1)); 188 | System.out.println(d3 + " before " + d2 + " should be false: " + 189 | d3.isBefore(d2)); 190 | 191 | System.out.println("\nTesting difference."); 192 | System.out.println(d1 + " - " + d1 + " should be 0: " + 193 | d1.difference(d1)); 194 | System.out.println(d2 + " - " + d1 + " should be 1: " + 195 | d2.difference(d1)); 196 | System.out.println(d3 + " - " + d1 + " should be 2: " + 197 | d3.difference(d1)); 198 | System.out.println(d3 + " - " + d4 + " should be -422: " + 199 | d3.difference(d4)); 200 | System.out.println(d5 + " - " + d4 + " should be 48762: " + 201 | d5.difference(d4)); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /hw/hw3/Homework3.java: -------------------------------------------------------------------------------- 1 | /* Homework3.java */ 2 | 3 | public class Homework3 { 4 | 5 | /** 6 | * smoosh() takes an array of ints. On completion the array contains 7 | * the same numbers, but wherever the array had two or more consecutive 8 | * duplicate numbers, they are replaced by one copy of the number. Hence, 9 | * after smoosh() is done, no two consecutive numbers in the array are the 10 | * same. 11 | * 12 | * Any unused elements at the end of the array are set to -1. 13 | * 14 | * For example, if the input array is [ 0 0 0 0 1 1 0 0 0 3 3 3 1 1 0 ], 15 | * it reads [ 0 1 0 3 1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] after smoosh() 16 | * completes. 17 | * 18 | * @param ints the input array. 19 | **/ 20 | 21 | public static void smoosh(int[] ints) { 22 | // Fill in your solution here. (Ours is twelve lines long, not counting 23 | // blank lines or lines already present in this file.) 24 | int k = 1; 25 | int copy = ints[0]; 26 | for(int i = 1; i < ints.length; i++){ 27 | if(copy != ints[i]){ 28 | copy = ints[i]; 29 | ints[k] = copy; 30 | k++; 31 | } 32 | } 33 | while(k < ints.length){ 34 | ints[k] = -1; 35 | k++; 36 | } 37 | } 38 | 39 | /** 40 | * stringInts() converts an array of ints to a String. 41 | * @return a String representation of the array. 42 | **/ 43 | 44 | private static String stringInts(int[] ints) { 45 | String s = "[ "; 46 | for (int i = 0; i < ints.length; i++) { 47 | s = s + Integer.toString(ints[i]) + " "; 48 | } 49 | return s + "]"; 50 | } 51 | 52 | /** 53 | * main() runs test cases on your smoosh and squish methods. Prints summary 54 | * information on basic operations and halts with an error (and a stack 55 | * trace) if any of the tests fail. 56 | **/ 57 | 58 | public static void main(String[] args) { 59 | String result; 60 | int i; 61 | 62 | 63 | System.out.println("Let's smoosh arrays!\n"); 64 | 65 | int[] test1 = {3, 7, 7, 7, 4, 5, 5, 2, 0, 8, 8, 8, 8, 5}; 66 | System.out.println("smooshing " + stringInts(test1) + ":"); 67 | smoosh(test1); 68 | result = stringInts(test1); 69 | System.out.println(result); 70 | TestHelper.verify(result.equals( 71 | "[ 3 7 4 5 2 0 8 5 -1 -1 -1 -1 -1 -1 ]"), 72 | "BAD SMOOSH!!! No cookie."); 73 | 74 | int[] test2 = {6, 6, 6, 6, 6, 3, 6, 3, 6, 3, 3, 3, 3, 3, 3}; 75 | System.out.println("smooshing " + stringInts(test2) + ":"); 76 | smoosh(test2); 77 | result = stringInts(test2); 78 | System.out.println(result); 79 | TestHelper.verify(result.equals( 80 | "[ 6 3 6 3 6 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 ]"), 81 | "BAD SMOOSH!!! No cookie."); 82 | 83 | int[] test3 = {4, 4, 4, 4, 4}; 84 | System.out.println("smooshing " + stringInts(test3) + ":"); 85 | smoosh(test3); 86 | result = stringInts(test3); 87 | System.out.println(result); 88 | TestHelper.verify(result.equals("[ 4 -1 -1 -1 -1 ]"), 89 | "BAD SMOOSH!!! No cookie."); 90 | 91 | int[] test4 = {0, 1, 2, 3, 4, 5, 6}; 92 | System.out.println("smooshing " + stringInts(test4) + ":"); 93 | smoosh(test4); 94 | result = stringInts(test4); 95 | System.out.println(result); 96 | TestHelper.verify(result.equals("[ 0 1 2 3 4 5 6 ]"), 97 | "BAD SMOOSH!!! No cookie."); 98 | 99 | 100 | System.out.println("\nLet's squish linked lists!\n"); 101 | 102 | int[] test5 = {3, 7, 7, 7, 4, 5, 5, 2, 0, 8, 8, 8, 8, 5}; 103 | SList list5 = new SList(); 104 | for (i = 0; i < test5.length; i++) { 105 | list5.insertEnd(new Integer(test5[i])); 106 | } 107 | System.out.println("squishing " + list5.toString() + ":"); 108 | list5.squish(); 109 | result = list5.toString(); 110 | System.out.println(result); 111 | TestHelper.verify(result.equals("[ 3 7 4 5 2 0 8 5 ]"), 112 | "BAD SQUISH!!! No biscuit."); 113 | 114 | int[] test6 = {6, 6, 6, 6, 6, 3, 6, 3, 6, 3, 3, 3, 3, 3, 3}; 115 | SList list6 = new SList(); 116 | for (i = 0; i < test6.length; i++) { 117 | list6.insertEnd(new Integer(test6[i])); 118 | } 119 | System.out.println("squishing " + list6.toString() + ":"); 120 | list6.squish(); 121 | result = list6.toString(); 122 | System.out.println(result); 123 | TestHelper.verify(result.equals("[ 6 3 6 3 6 3 ]"), 124 | "BAD SQUISH!!! No biscuit."); 125 | 126 | int[] test7 = {4, 4, 4, 4, 4}; 127 | SList list7 = new SList(); 128 | for (i = 0; i < test7.length; i++) { 129 | list7.insertEnd(new Integer(test7[i])); 130 | } 131 | System.out.println("squishing " + list7.toString() + ":"); 132 | list7.squish(); 133 | result = list7.toString(); 134 | System.out.println(result); 135 | TestHelper.verify(result.equals("[ 4 ]"), 136 | "BAD SQUISH!!! No biscuit."); 137 | 138 | int[] test8 = {0, 1, 2, 3, 4, 5, 6}; 139 | SList list8 = new SList(); 140 | for (i = 0; i < test8.length; i++) { 141 | list8.insertEnd(new Integer(test8[i])); 142 | } 143 | System.out.println("squishing " + list8.toString() + ":"); 144 | list8.squish(); 145 | result = list8.toString(); 146 | System.out.println(result); 147 | TestHelper.verify(result.equals("[ 0 1 2 3 4 5 6 ]"), 148 | "BAD SQUISH!!! No biscuit."); 149 | 150 | SList list9 = new SList(); 151 | System.out.println("squishing " + list9.toString() + ":"); 152 | list9.squish(); 153 | result = list9.toString(); 154 | System.out.println(result); 155 | TestHelper.verify(result.equals("[ ]"), 156 | "BAD SQUISH!!! No biscuit."); 157 | 158 | 159 | System.out.println("\nLet's twin linked lists!\n"); 160 | 161 | System.out.println("twinning " + list6.toString() + ":"); 162 | list6.twin(); 163 | result = list6.toString(); 164 | System.out.println(result); 165 | TestHelper.verify(result.equals( 166 | "[ 6 6 3 3 6 6 3 3 6 6 3 3 ]"), 167 | "BAD TWIN!!! No gravy."); 168 | 169 | System.out.println("twinning " + list7.toString() + ":"); 170 | list7.twin(); 171 | result = list7.toString(); 172 | System.out.println(result); 173 | TestHelper.verify(result.equals("[ 4 4 ]"), 174 | "BAD TWIN!!! No gravy."); 175 | 176 | System.out.println("twinning " + list9.toString() + ":"); 177 | list9.twin(); 178 | result = list9.toString(); 179 | System.out.println(result); 180 | TestHelper.verify(result.equals("[ ]"), 181 | "BAD TWIN!!! No gravy."); 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /hw/hw3/SListNode.java: -------------------------------------------------------------------------------- 1 | /* SListNode.java */ 2 | 3 | /** 4 | * SListNode is a class used internally by the SList class. An SList object 5 | * is a singly-linked list, and an SListNode is a node of a singly-linked 6 | * list. Each SListNode has two references: one to an object, and one to 7 | * the next node in the list. 8 | * 9 | * @author Kathy Yelick and Jonathan Shewchuk 10 | */ 11 | 12 | class SListNode { 13 | Object item; 14 | SListNode next; 15 | 16 | 17 | /** 18 | * SListNode() (with two parameters) constructs a list node referencing the 19 | * item "obj", whose next list node is to be "next". 20 | */ 21 | 22 | SListNode(Object obj, SListNode next) { 23 | item = obj; 24 | this.next = next; 25 | } 26 | 27 | /** 28 | * SListNode() (with one parameter) constructs a list node referencing the 29 | * item "obj". 30 | */ 31 | 32 | SListNode(Object obj) { 33 | this(obj, null); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /hw/hw3/TestHelper.java: -------------------------------------------------------------------------------- 1 | /* TestHelper.java */ 2 | 3 | /** 4 | * The purpose of this class is to provide a shorthand for writing and testing 5 | * invariants in any program. 6 | **/ 7 | 8 | public class TestHelper { 9 | 10 | /** 11 | * verify() checks an invariant and prints an error message if it fails. 12 | * If invariant is true, this method does nothing. If invariant is false, 13 | * the message is printed, followed by a dump of the program stack. 14 | * 15 | * @param invariant the condition to be verified 16 | * @param message the error message to be printed if the invariant fails to 17 | * hold true. 18 | **/ 19 | 20 | static void verify(boolean invariant, String message) { 21 | if (!invariant) { 22 | System.out.println("*** ERROR: " + message); 23 | Thread.dumpStack(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /hw/hw4/list/DList.java: -------------------------------------------------------------------------------- 1 | /* DList.java */ 2 | 3 | package list; 4 | 5 | /** 6 | * A DList is a mutable doubly-linked list ADT. Its implementation is 7 | * circularly-linked and employs a sentinel (dummy) node at the head 8 | * of the list. 9 | * 10 | * DO NOT CHANGE ANY METHOD PROTOTYPES IN THIS FILE. 11 | */ 12 | 13 | public class DList { 14 | 15 | /** 16 | * head references the sentinel node. 17 | * size is the number of items in the list. (The sentinel node does not 18 | * store an item.) 19 | * 20 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 21 | */ 22 | 23 | protected DListNode head; 24 | protected int size; 25 | 26 | /* DList invariants: 27 | * 1) head != null. 28 | * 2) For any DListNode x in a DList, x.next != null. 29 | * 3) For any DListNode x in a DList, x.prev != null. 30 | * 4) For any DListNode x in a DList, if x.next == y, then y.prev == x. 31 | * 5) For any DListNode x in a DList, if x.prev == y, then y.next == x. 32 | * 6) size is the number of DListNodes, NOT COUNTING the sentinel, 33 | * that can be accessed from the sentinel (head) by a sequence of 34 | * "next" references. 35 | */ 36 | 37 | /** 38 | * newNode() calls the DListNode constructor. Use this class to allocate 39 | * new DListNodes rather than calling the DListNode constructor directly. 40 | * That way, only this method needs to be overridden if a subclass of DList 41 | * wants to use a different kind of node. 42 | * @param item the item to store in the node. 43 | * @param prev the node previous to this node. 44 | * @param next the node following this node. 45 | */ 46 | protected DListNode newNode(Object item, DListNode prev, DListNode next) { 47 | return new DListNode(item, prev, next); 48 | } 49 | 50 | /** 51 | * DList() constructor for an empty DList. 52 | */ 53 | public DList() { 54 | // Your solution here. 55 | head = newNode(null, null, null); 56 | head.prev = head; 57 | head.next =head; 58 | size = 0; 59 | } 60 | 61 | /** 62 | * isEmpty() returns true if this DList is empty, false otherwise. 63 | * @return true if this DList is empty, false otherwise. 64 | * Performance: runs in O(1) time. 65 | */ 66 | public boolean isEmpty() { 67 | return size == 0; 68 | } 69 | 70 | /** 71 | * length() returns the length of this DList. 72 | * @return the length of this DList. 73 | * Performance: runs in O(1) time. 74 | */ 75 | public int length() { 76 | return size; 77 | } 78 | 79 | /** 80 | * insertFront() inserts an item at the front of this DList. 81 | * @param item is the item to be inserted. 82 | * Performance: runs in O(1) time. 83 | */ 84 | public void insertFront(Object item) { 85 | // Your solution here. 86 | head.next = newNode(item, head, head.next); 87 | head.next.next.prev = head.next; 88 | size++; 89 | } 90 | 91 | /** 92 | * insertBack() inserts an item at the back of this DList. 93 | * @param item is the item to be inserted. 94 | * Performance: runs in O(1) time. 95 | */ 96 | public void insertBack(Object item) { 97 | // Your solution here. 98 | head.prev = newNode(item, head.prev, head); 99 | head.prev.prev.next = head.prev; 100 | size++; 101 | } 102 | 103 | /** 104 | * front() returns the node at the front of this DList. If the DList is 105 | * empty, return null. 106 | * 107 | * Do NOT return the sentinel under any circumstances! 108 | * 109 | * @return the node at the front of this DList. 110 | * Performance: runs in O(1) time. 111 | */ 112 | public DListNode front() { 113 | // Your solution here. 114 | if(size == 0){ 115 | return null; 116 | }else{ 117 | return head.next; 118 | } 119 | } 120 | 121 | /** 122 | * back() returns the node at the back of this DList. If the DList is 123 | * empty, return null. 124 | * 125 | * Do NOT return the sentinel under any circumstances! 126 | * 127 | * @return the node at the back of this DList. 128 | * Performance: runs in O(1) time. 129 | */ 130 | public DListNode back() { 131 | // Your solution here. 132 | if(size == 0){ 133 | return null; 134 | }else{ 135 | return head.prev; 136 | } 137 | } 138 | 139 | /** 140 | * next() returns the node following "node" in this DList. If "node" is 141 | * null, or "node" is the last node in this DList, return null. 142 | * 143 | * Do NOT return the sentinel under any circumstances! 144 | * 145 | * @param node the node whose successor is sought. 146 | * @return the node following "node". 147 | * Performance: runs in O(1) time. 148 | */ 149 | public DListNode next(DListNode node) { 150 | // Your solution here. 151 | if(size == 0 || node == head.prev){ 152 | return null; 153 | }else{ 154 | return node.next; 155 | } 156 | } 157 | 158 | /** 159 | * prev() returns the node prior to "node" in this DList. If "node" is 160 | * null, or "node" is the first node in this DList, return null. 161 | * 162 | * Do NOT return the sentinel under any circumstances! 163 | * 164 | * @param node the node whose predecessor is sought. 165 | * @return the node prior to "node". 166 | * Performance: runs in O(1) time. 167 | */ 168 | public DListNode prev(DListNode node) { 169 | // Your solution here. 170 | if(size == 0 || node == head.next){ 171 | return null; 172 | }else{ 173 | return node.prev; 174 | } 175 | } 176 | 177 | /** 178 | * insertAfter() inserts an item in this DList immediately following "node". 179 | * If "node" is null, do nothing. 180 | * @param item the item to be inserted. 181 | * @param node the node to insert the item after. 182 | * Performance: runs in O(1) time. 183 | */ 184 | public void insertAfter(Object item, DListNode node) { 185 | // Your solution here. 186 | if(node != null){ 187 | node.next = newNode(item, node, node.next); 188 | node.next.next.prev = node.next; 189 | size++; 190 | } 191 | } 192 | 193 | /** 194 | * insertBefore() inserts an item in this DList immediately before "node". 195 | * If "node" is null, do nothing. 196 | * @param item the item to be inserted. 197 | * @param node the node to insert the item before. 198 | * Performance: runs in O(1) time. 199 | */ 200 | public void insertBefore(Object item, DListNode node) { 201 | // Your solution here. 202 | if(node != null){ 203 | node.prev = newNode(item, node.prev, node); 204 | node.prev.prev.next = node.prev; 205 | size++; 206 | } 207 | } 208 | 209 | /** 210 | * remove() removes "node" from this DList. If "node" is null, do nothing. 211 | * Performance: runs in O(1) time. 212 | */ 213 | public void remove(DListNode node) { 214 | // Your solution here. 215 | if(node !=null){ 216 | node.prev.next = node.next; 217 | node.next.prev = node.prev; 218 | size--; 219 | } 220 | } 221 | 222 | /** 223 | * toString() returns a String representation of this DList. 224 | * 225 | * DO NOT CHANGE THIS METHOD. 226 | * 227 | * @return a String representation of this DList. 228 | * Performance: runs in O(n) time, where n is the length of the list. 229 | */ 230 | public String toString() { 231 | String result = "[ "; 232 | DListNode current = head.next; 233 | while (current != head) { 234 | result = result + current.item + " "; 235 | current = current.next; 236 | } 237 | return result + "]"; 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /hw/hw4/list/DListNode.java: -------------------------------------------------------------------------------- 1 | /* DListNode.java */ 2 | 3 | package list; 4 | 5 | /** 6 | * A DListNode is a node in a DList (doubly-linked list). 7 | */ 8 | 9 | public class DListNode { 10 | 11 | /** 12 | * item references the item stored in the current node. 13 | * prev references the previous node in the DList. 14 | * next references the next node in the DList. 15 | * 16 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 17 | */ 18 | 19 | public Object item; 20 | protected DListNode prev; 21 | protected DListNode next; 22 | 23 | /** 24 | * DListNode() constructor. 25 | * @param i the item to store in the node. 26 | * @param p the node previous to this node. 27 | * @param n the node following this node. 28 | */ 29 | DListNode(Object i, DListNode p, DListNode n) { 30 | item = i; 31 | prev = p; 32 | next = n; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /hw/hw4/list/LockDList.java: -------------------------------------------------------------------------------- 1 | package list; 2 | 3 | public class LockDList extends DList { 4 | 5 | protected LockDListNode newNode(Object item, DListNode prev, DListNode next){ 6 | return new LockDListNode(item, prev, next); 7 | } 8 | 9 | public void lockNode(DListNode node){ 10 | LockDListNode temp = (LockDListNode)node; 11 | temp.lock = true; 12 | } 13 | 14 | public LockDListNode front(){ 15 | return (LockDListNode)(super.front()); 16 | } 17 | 18 | public LockDListNode back(){ 19 | return (LockDListNode)(super.back()); 20 | } 21 | 22 | public LockDListNode next(DListNode node){ 23 | return (LockDListNode)(super.next(node)); 24 | } 25 | 26 | public LockDListNode prev(DListNode node){ 27 | return (LockDListNode)(super.prev(node)); 28 | } 29 | 30 | public void remove(DListNode node){ 31 | if(node !=null){ 32 | if(((LockDListNode)node).lock !=true){ 33 | node.prev.next = node.next; 34 | node.next.prev = node.prev; 35 | size--; 36 | } 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /hw/hw4/list/LockDListNode.java: -------------------------------------------------------------------------------- 1 | package list; 2 | 3 | public class LockDListNode extends DListNode { 4 | 5 | protected boolean lock; 6 | 7 | LockDListNode(Object i, DListNode p, DListNode n){ 8 | super(i, p, n); 9 | lock = false; 10 | } 11 | } -------------------------------------------------------------------------------- /hw/hw4/list/TestDList.java: -------------------------------------------------------------------------------- 1 | package list; 2 | public class TestDList { 3 | public static void main (String[] args) { 4 | // Fill in your solution for Part I here. 5 | System.out.println("Now we are testing DList."); 6 | DList sl1 = new DList(); 7 | sl1.insertBack(new Integer(6)); 8 | sl1.insertBack(new Integer(9)); 9 | sl1.insertBack(new Integer(12)); 10 | System.out.println("Here is a list after insertBack 6, 9, 12: " 11 | + sl1.toString()); 12 | System.out.println(); 13 | 14 | 15 | sl1.insertFront(new Integer(3)); 16 | sl1.insertBack(new Integer(15)); 17 | System.out.println("Here is the same list after insertBack(15) and insertFront(3): " 18 | + sl1.toString()); 19 | newtest(sl1); 20 | 21 | testEmpty(); 22 | testAfterInsertFront(); 23 | testAfterinsertBack(); 24 | } 25 | 26 | 27 | /** 28 | * testEmpty() tests toString(), isEmpty(), length(), insertFront(), and 29 | * insertBack() on an empty list. Prints summary information of the tests 30 | * and halts the program if errors are detected. 31 | **/ 32 | 33 | private static void testEmpty() { 34 | DList lst1 = new DList(); 35 | DList lst2 = new DList(); 36 | System.out.println(); 37 | System.out.println("Here is a list after construction: " 38 | + lst1.toString()); 39 | TestHelper.verify(lst1.toString().equals("[ ]"), 40 | "toString on newly constructed list failed"); 41 | 42 | System.out.println("isEmpty() should be true. It is: " + 43 | lst1.isEmpty()); 44 | TestHelper.verify(lst1.isEmpty() == true, 45 | "isEmpty() on newly constructed list failed"); 46 | 47 | System.out.println("length() should be 0. It is: " + 48 | lst1.length()); 49 | TestHelper.verify(lst1.length() == 0, 50 | "length on newly constructed list failed"); 51 | lst1.insertFront(new Integer(3)); 52 | System.out.println("Here is a list after insertFront(3) to an empty list: " 53 | + lst1.toString()); 54 | TestHelper.verify(lst1.toString().equals("[ 3 ]"), 55 | "InsertFront on empty list failed"); 56 | lst2.insertBack(new Integer(5)); 57 | System.out.println("Here is a list after insertBack(5) on an empty list: " 58 | + lst2.toString()); 59 | TestHelper.verify(lst2.toString().equals("[ 5 ]"), 60 | "insertBack on empty list failed"); 61 | } 62 | 63 | /** 64 | * testAfterInsertFront() tests toString(), isEmpty(), length(), 65 | * insertFront(), and insertBack() after insertFront(). Prints summary 66 | * information of the tests and halts the program if errors are detected. 67 | **/ 68 | 69 | private static void testAfterInsertFront() { 70 | DList lst1 = new DList(); 71 | lst1.insertFront(new Integer(3)); 72 | lst1.insertFront(new Integer(2)); 73 | lst1.insertFront(new Integer(1)); 74 | System.out.println(); 75 | System.out.println("Here is a list after insertFront 3, 2, 1: " 76 | + lst1.toString()); 77 | TestHelper.verify(lst1.toString().equals("[ 1 2 3 ]"), 78 | "InsertFronts on non-empty list failed"); 79 | System.out.println("isEmpty() should be false. It is: " + 80 | lst1.isEmpty()); 81 | TestHelper.verify(lst1.isEmpty() == false, 82 | "isEmpty() after insertFront failed"); 83 | System.out.println("length() should be 3. It is: " + 84 | lst1.length()); 85 | TestHelper.verify(lst1.length() == 3, 86 | "length() after insertFront failed"); 87 | lst1.insertBack(new Integer(4)); 88 | System.out.println("Here is the same list after insertBack(4): " 89 | + lst1.toString()); 90 | TestHelper.verify(lst1.toString().equals("[ 1 2 3 4 ]"), 91 | "insertBack on non-empty list failed"); 92 | } 93 | 94 | /** 95 | * testAfterinsertBack() tests toString(), isEmpty(), length(), 96 | * insertFront(), and insertBack() after insertBack(). Prints summary 97 | * information of the tests and halts the program if errors are detected. 98 | **/ 99 | 100 | private static void testAfterinsertBack() { 101 | DList lst1 = new DList(); 102 | lst1.insertBack(new Integer(6)); 103 | lst1.insertBack(new Integer(7)); 104 | System.out.println(); 105 | System.out.println("Here is a list after insertBack 6, 7: " 106 | + lst1.toString()); 107 | System.out.println("isEmpty() should be false. It is: " + 108 | lst1.isEmpty()); 109 | TestHelper.verify(lst1.isEmpty() == false, 110 | "isEmpty() after insertBack failed"); 111 | System.out.println("length() should be 2. It is: " + 112 | lst1.length()); 113 | TestHelper.verify(lst1.length() == 2, 114 | "length() after insertBackfailed"); 115 | lst1.insertFront(new Integer(5)); 116 | System.out.println("Here is the same list after insertFront(5): " 117 | + lst1.toString()); 118 | TestHelper.verify(lst1.toString().equals("[ 5 6 7 ]"), 119 | "insertFront after insertBack failed"); 120 | } 121 | private static void newtest(DList sl1) { 122 | DListNode node = sl1.front(); 123 | System.out.println(); 124 | System.out.println("front() should be 3. It is: " + 125 | sl1.front().item); 126 | System.out.println("front's next should be 6. It is: " + 127 | sl1.next(node).item); 128 | System.out.println("front's next's prev should be 3. It is: " + 129 | sl1.prev(sl1.next(node)).item); 130 | sl1.remove(node); 131 | System.out.println("After remove the front, the front() should be 6. It is: " + 132 | sl1.front().item); 133 | node = sl1.front(); 134 | sl1.insertBefore(new Integer(5),node); 135 | sl1.insertAfter(new Integer(8),node); 136 | System.out.println("After insertBefore() and insertAfter(), The first 3 nodes should be 5,6,8. The list is: " + 137 | sl1.toString()); 138 | 139 | } 140 | } -------------------------------------------------------------------------------- /hw/hw4/list/TestHelper.java: -------------------------------------------------------------------------------- 1 | /* TestHelper.java */ 2 | package list; 3 | /** 4 | * This class is based on code from Arnow/Dexter/Weiss. Its verify() method 5 | * exits with an error message if an invariant fails to hold true. 6 | * 7 | * The purpose of this class is to provide a shorthand for writing and testing 8 | * invariants in any program. 9 | **/ 10 | 11 | public class TestHelper { 12 | 13 | /** 14 | * verify() checks an invariant and prints an error message if it fails. 15 | * If invariant is true, this method does nothing. If invariant is false, 16 | * the message is printed, followed by a dump of the program call stack. 17 | * 18 | * @param invariant the condition to be verified 19 | * @param message the error message to be printed if the invariant fails to 20 | * hold true. 21 | **/ 22 | 23 | static void verify(boolean invariant, String message) { 24 | if (!invariant) { 25 | System.out.println("*** ERROR: " + message); 26 | Thread.dumpStack(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /hw/hw4/list/TestLockDList.java: -------------------------------------------------------------------------------- 1 | package list; 2 | public class TestLockDList { 3 | public static void main (String[] args) { 4 | // Fill in your solution for Part I here. 5 | System.out.println("Now we are testing LockDList."); 6 | LockDList sl1 = new LockDList(); 7 | sl1.insertBack(new Integer(6)); 8 | sl1.insertBack(new Integer(9)); 9 | sl1.insertBack(new Integer(12)); 10 | System.out.println("Here is a list after insertBack 6, 9, 12: " 11 | + sl1.toString()); 12 | System.out.println(); 13 | 14 | 15 | sl1.insertFront(new Integer(3)); 16 | sl1.insertBack(new Integer(15)); 17 | System.out.println("Here is the same list after insertBack(15) and insertFront(3): " 18 | + sl1.toString()); 19 | newtest(sl1); 20 | 21 | testEmpty(); 22 | testAfterInsertFront(); 23 | testAfterinsertBack(); 24 | } 25 | 26 | 27 | /** 28 | * testEmpty() tests toString(), isEmpty(), length(), insertFront(), and 29 | * insertBack() on an empty list. Prints summary information of the tests 30 | * and halts the program if errors are detected. 31 | **/ 32 | 33 | private static void testEmpty() { 34 | LockDList lst1 = new LockDList(); 35 | LockDList lst2 = new LockDList(); 36 | System.out.println(); 37 | System.out.println("Here is a list after construction: " 38 | + lst1.toString()); 39 | TestHelper.verify(lst1.toString().equals("[ ]"), 40 | "toString on newly constructed list failed"); 41 | 42 | System.out.println("isEmpty() should be true. It is: " + 43 | lst1.isEmpty()); 44 | TestHelper.verify(lst1.isEmpty() == true, 45 | "isEmpty() on newly constructed list failed"); 46 | 47 | System.out.println("length() should be 0. It is: " + 48 | lst1.length()); 49 | TestHelper.verify(lst1.length() == 0, 50 | "length on newly constructed list failed"); 51 | lst1.insertFront(new Integer(3)); 52 | System.out.println("Here is a list after insertFront(3) to an empty list: " 53 | + lst1.toString()); 54 | TestHelper.verify(lst1.toString().equals("[ 3 ]"), 55 | "InsertFront on empty list failed"); 56 | lst2.insertBack(new Integer(5)); 57 | System.out.println("Here is a list after insertBack(5) on an empty list: " 58 | + lst2.toString()); 59 | TestHelper.verify(lst2.toString().equals("[ 5 ]"), 60 | "insertBack on empty list failed"); 61 | } 62 | 63 | /** 64 | * testAfterInsertFront() tests toString(), isEmpty(), length(), 65 | * insertFront(), and insertBack() after insertFront(). Prints summary 66 | * information of the tests and halts the program if errors are detected. 67 | **/ 68 | 69 | private static void testAfterInsertFront() { 70 | LockDList lst1 = new LockDList(); 71 | lst1.insertFront(new Integer(3)); 72 | lst1.insertFront(new Integer(2)); 73 | lst1.insertFront(new Integer(1)); 74 | System.out.println(); 75 | System.out.println("Here is a list after insertFront 3, 2, 1: " 76 | + lst1.toString()); 77 | TestHelper.verify(lst1.toString().equals("[ 1 2 3 ]"), 78 | "InsertFronts on non-empty list failed"); 79 | System.out.println("isEmpty() should be false. It is: " + 80 | lst1.isEmpty()); 81 | TestHelper.verify(lst1.isEmpty() == false, 82 | "isEmpty() after insertFront failed"); 83 | System.out.println("length() should be 3. It is: " + 84 | lst1.length()); 85 | TestHelper.verify(lst1.length() == 3, 86 | "length() after insertFront failed"); 87 | lst1.insertBack(new Integer(4)); 88 | System.out.println("Here is the same list after insertBack(4): " 89 | + lst1.toString()); 90 | TestHelper.verify(lst1.toString().equals("[ 1 2 3 4 ]"), 91 | "insertBack on non-empty list failed"); 92 | } 93 | 94 | /** 95 | * testAfterinsertBack() tests toString(), isEmpty(), length(), 96 | * insertFront(), and insertBack() after insertBack(). Prints summary 97 | * information of the tests and halts the program if errors are detected. 98 | **/ 99 | 100 | private static void testAfterinsertBack() { 101 | LockDList lst1 = new LockDList(); 102 | lst1.insertBack(new Integer(6)); 103 | lst1.insertBack(new Integer(7)); 104 | System.out.println(); 105 | System.out.println("Here is a list after insertBack 6, 7: " 106 | + lst1.toString()); 107 | System.out.println("isEmpty() should be false. It is: " + 108 | lst1.isEmpty()); 109 | TestHelper.verify(lst1.isEmpty() == false, 110 | "isEmpty() after insertBack failed"); 111 | System.out.println("length() should be 2. It is: " + 112 | lst1.length()); 113 | TestHelper.verify(lst1.length() == 2, 114 | "length() after insertBackfailed"); 115 | lst1.insertFront(new Integer(5)); 116 | System.out.println("Here is the same list after insertFront(5): " 117 | + lst1.toString()); 118 | TestHelper.verify(lst1.toString().equals("[ 5 6 7 ]"), 119 | "insertFront after insertBack failed"); 120 | } 121 | private static void newtest(LockDList sl1) { 122 | LockDListNode node = sl1.front(); 123 | System.out.println(); 124 | System.out.println("front() should be 3. It is: " + 125 | sl1.front().item); 126 | System.out.println("front's next should be 6. It is: " + 127 | sl1.next(node).item); 128 | System.out.println("front's next's prev should be 3. It is: " + 129 | sl1.prev(sl1.next(node)).item); 130 | sl1.lockNode(node); 131 | System.out.println("We lockNode front()= "+node.item); 132 | sl1.remove(node); 133 | System.out.println("After remove the locked front, the front() should still be 3. It is: " + 134 | sl1.front().item); 135 | LockDListNode back = sl1.back(); 136 | sl1.remove(back); 137 | System.out.println("After remove the back, the back() should be 12. It is: " + 138 | sl1.back().item); 139 | node = sl1.front(); 140 | sl1.insertBefore(new Integer(5),node); 141 | sl1.insertAfter(new Integer(8),node); 142 | System.out.println("After insertBefore(3) and insertAfter(3), The first 3 nodes should be 5,3,8. The list is: " + 143 | sl1.toString()); 144 | 145 | } 146 | } -------------------------------------------------------------------------------- /hw/hw5/list/DListNode.java: -------------------------------------------------------------------------------- 1 | /* DListNode.java */ 2 | 3 | package list; 4 | 5 | /** 6 | * A DListNode is a mutable node in a DList (doubly-linked list). 7 | **/ 8 | 9 | public class DListNode extends ListNode { 10 | 11 | /** 12 | * (inherited) item references the item stored in the current node. 13 | * (inherited) myList references the List that contains this node. 14 | * prev references the previous node in the DList. 15 | * next references the next node in the DList. 16 | * 17 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 18 | **/ 19 | 20 | protected DListNode prev; 21 | protected DListNode next; 22 | 23 | /** 24 | * DListNode() constructor. 25 | * @param i the item to store in the node. 26 | * @param l the list this node is in. 27 | * @param p the node previous to this node. 28 | * @param n the node following this node. 29 | */ 30 | DListNode(Object i, DList l, DListNode p, DListNode n) { 31 | item = i; 32 | myList = l; 33 | prev = p; 34 | next = n; 35 | } 36 | 37 | /** 38 | * isValidNode returns true if this node is valid; false otherwise. 39 | * An invalid node is represented by a `myList' field with the value null. 40 | * Sentinel nodes are invalid, and nodes that don't belong to a list are 41 | * also invalid. 42 | * 43 | * @return true if this node is valid; false otherwise. 44 | * 45 | * Performance: runs in O(1) time. 46 | */ 47 | public boolean isValidNode() { 48 | return myList != null; 49 | } 50 | 51 | /** 52 | * next() returns the node following this node. If this node is invalid, 53 | * throws an exception. 54 | * 55 | * @return the node following this node. 56 | * @exception InvalidNodeException if this node is not valid. 57 | * 58 | * Performance: runs in O(1) time. 59 | */ 60 | public ListNode next() throws InvalidNodeException { 61 | if (!isValidNode()) { 62 | throw new InvalidNodeException("next() called on invalid node"); 63 | } 64 | return next; 65 | } 66 | 67 | /** 68 | * prev() returns the node preceding this node. If this node is invalid, 69 | * throws an exception. 70 | * 71 | * @return the node preceding this node. 72 | * @exception InvalidNodeException if this node is not valid. 73 | * 74 | * Performance: runs in O(1) time. 75 | */ 76 | public ListNode prev() throws InvalidNodeException { 77 | if (!isValidNode()) { 78 | throw new InvalidNodeException("prev() called on invalid node"); 79 | } 80 | return prev; 81 | } 82 | 83 | /** 84 | * insertAfter() inserts an item immediately following this node. If this 85 | * node is invalid, throws an exception. 86 | * 87 | * @param item the item to be inserted. 88 | * @exception InvalidNodeException if this node is not valid. 89 | * 90 | * Performance: runs in O(1) time. 91 | */ 92 | public void insertAfter(Object item) throws InvalidNodeException { 93 | if (!isValidNode()) { 94 | throw new InvalidNodeException("insertAfter() called on invalid node"); 95 | } 96 | // Your solution here. Will look something like your Homework 4 solution, 97 | // but changes are necessary. For instance, there is no need to check if 98 | // "this" is null. Remember that this node's "myList" field tells you 99 | // what DList it's in. You should use myList.newNode() to create the 100 | // new node. 101 | this.next = ((DList)this.myList).newNode(item, (DList)this.myList, this, this.next); 102 | this.next.next.prev = this.next; 103 | this.myList.size++; 104 | } 105 | 106 | /** 107 | * insertBefore() inserts an item immediately preceding this node. If this 108 | * node is invalid, throws an exception. 109 | * 110 | * @param item the item to be inserted. 111 | * @exception InvalidNodeException if this node is not valid. 112 | * 113 | * Performance: runs in O(1) time. 114 | */ 115 | public void insertBefore(Object item) throws InvalidNodeException { 116 | if (!isValidNode()) { 117 | throw new InvalidNodeException("insertBefore() called on invalid node"); 118 | } 119 | // Your solution here. Will look something like your Homework 4 solution, 120 | // but changes are necessary. For instance, there is no need to check if 121 | // "this" is null. Remember that this node's "myList" field tells you 122 | // what DList it's in. You should use myList.newNode() to create the 123 | // new node. 124 | this.prev = ((DList)this.myList).newNode(item, (DList)this.myList, this.prev, this); 125 | this.prev.prev.next = this.prev; 126 | this.myList.size++; 127 | } 128 | 129 | /** 130 | * remove() removes this node from its DList. If this node is invalid, 131 | * throws an exception. 132 | * 133 | * @exception InvalidNodeException if this node is not valid. 134 | * 135 | * Performance: runs in O(1) time. 136 | */ 137 | public void remove() throws InvalidNodeException { 138 | if (!isValidNode()) { 139 | throw new InvalidNodeException("remove() called on invalid node"); 140 | } 141 | // Your solution here. Will look something like your Homework 4 solution, 142 | // but changes are necessary. For instance, there is no need to check if 143 | // "this" is null. Remember that this node's "myList" field tells you 144 | // what DList it's in. 145 | this.prev.next = this.next; 146 | this.next.prev = this.prev; 147 | this.myList.size--; 148 | 149 | // Make this node an invalid node, so it cannot be used to corrupt myList. 150 | myList = null; 151 | // Set other references to null to improve garbage collection. 152 | next = null; 153 | prev = null; 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /hw/hw5/list/InvalidNodeException.java: -------------------------------------------------------------------------------- 1 | /* InvalidNodeException.java */ 2 | 3 | package list; 4 | 5 | /** 6 | * Implements an Exception that signals an attempt to use an invalid ListNode. 7 | */ 8 | 9 | public class InvalidNodeException extends Exception { 10 | protected InvalidNodeException() { 11 | super(); 12 | } 13 | 14 | protected InvalidNodeException(String s) { 15 | super(s); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /hw/hw5/list/List.java: -------------------------------------------------------------------------------- 1 | /* List.java */ 2 | 3 | package list; 4 | 5 | /** 6 | * A List is a mutable list ADT. No implementation is provided. 7 | * 8 | * DO NOT CHANGE THIS FILE. 9 | **/ 10 | 11 | public abstract class List { 12 | 13 | /** 14 | * size is the number of items in the list. 15 | **/ 16 | 17 | protected int size; 18 | 19 | /** 20 | * isEmpty() returns true if this List is empty, false otherwise. 21 | * 22 | * @return true if this List is empty, false otherwise. 23 | * 24 | * Performance: runs in O(1) time. 25 | **/ 26 | public boolean isEmpty() { 27 | return size == 0; 28 | } 29 | 30 | /** 31 | * length() returns the length of this List. 32 | * 33 | * @return the length of this List. 34 | * 35 | * Performance: runs in O(1) time. 36 | **/ 37 | public int length() { 38 | return size; 39 | } 40 | 41 | /** 42 | * insertFront() inserts an item at the front of this List. 43 | * 44 | * @param item is the item to be inserted. 45 | **/ 46 | public abstract void insertFront(Object item); 47 | 48 | /** 49 | * insertBack() inserts an item at the back of this List. 50 | * 51 | * @param item is the item to be inserted. 52 | **/ 53 | public abstract void insertBack(Object item); 54 | 55 | /** 56 | * front() returns the node at the front of this List. If the List is 57 | * empty, return an "invalid" node--a node with the property that any 58 | * attempt to use it will cause an exception. 59 | * 60 | * @return a ListNode at the front of this List. 61 | */ 62 | public abstract ListNode front(); 63 | 64 | /** 65 | * back() returns the node at the back of this List. If the List is 66 | * empty, return an "invalid" node--a node with the property that any 67 | * attempt to use it will cause an exception. 68 | * 69 | * @return a ListNode at the back of this List. 70 | */ 71 | public abstract ListNode back(); 72 | 73 | /** 74 | * toString() returns a String representation of this List. 75 | * 76 | * @return a String representation of this List. 77 | */ 78 | public abstract String toString(); 79 | 80 | } 81 | -------------------------------------------------------------------------------- /hw/hw5/list/ListNode.java: -------------------------------------------------------------------------------- 1 | /* ListNode.java */ 2 | 3 | package list; 4 | 5 | /** 6 | * A ListNode is a mutable node in a list. No implementation is provided. 7 | * 8 | * DO NOT CHANGE THIS FILE. 9 | **/ 10 | 11 | public abstract class ListNode { 12 | 13 | /** 14 | * item references the item stored in the current node. 15 | * myList references the List that contains this node. 16 | * 17 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 18 | */ 19 | 20 | protected Object item; 21 | protected List myList; 22 | 23 | /** 24 | * isValidNode returns true if this node is valid; false otherwise. 25 | * By default, an invalid node is one that doesn't belong to a list (myList 26 | * is null), but subclasses can override this definition. 27 | * 28 | * @return true if this node is valid; false otherwise. 29 | * 30 | * Performance: runs in O(1) time. 31 | */ 32 | public boolean isValidNode() { 33 | return myList != null; 34 | } 35 | 36 | /** 37 | * item() returns this node's item. If this node is invalid, 38 | * throws an exception. 39 | * 40 | * @return the item stored in this node. 41 | * 42 | * Performance: runs in O(1) time. 43 | */ 44 | public Object item() throws InvalidNodeException { 45 | if (!isValidNode()) { 46 | throw new InvalidNodeException(); 47 | } 48 | return item; 49 | } 50 | 51 | /** 52 | * setItem() sets this node's item to "item". If this node is invalid, 53 | * throws an exception. 54 | * 55 | * Performance: runs in O(1) time. 56 | */ 57 | public void setItem(Object item) throws InvalidNodeException { 58 | if (!isValidNode()) { 59 | throw new InvalidNodeException(); 60 | } 61 | this.item = item; 62 | } 63 | 64 | /** 65 | * next() returns the node following this node. If this node is invalid, 66 | * throws an exception. 67 | * 68 | * @return the node following this node. 69 | * @exception InvalidNodeException if this node is not valid. 70 | */ 71 | public abstract ListNode next() throws InvalidNodeException; 72 | 73 | /** 74 | * prev() returns the node preceding this node. If this node is invalid, 75 | * throws an exception. 76 | * 77 | * @param node the node whose predecessor is sought. 78 | * @return the node preceding this node. 79 | * @exception InvalidNodeException if this node is not valid. 80 | */ 81 | public abstract ListNode prev() throws InvalidNodeException; 82 | 83 | /** 84 | * insertAfter() inserts an item immediately following this node. If this 85 | * node is invalid, throws an exception. 86 | * 87 | * @param item the item to be inserted. 88 | * @exception InvalidNodeException if this node is not valid. 89 | */ 90 | public abstract void insertAfter(Object item) throws InvalidNodeException; 91 | 92 | /** 93 | * insertBefore() inserts an item immediately preceding this node. If this 94 | * node is invalid, throws an exception. 95 | * 96 | * @param item the item to be inserted. 97 | * @exception InvalidNodeException if this node is not valid. 98 | */ 99 | public abstract void insertBefore(Object item) throws InvalidNodeException; 100 | 101 | /** 102 | * remove() removes this node from its List. If this node is invalid, 103 | * throws an exception. 104 | * 105 | * @exception InvalidNodeException if this node is not valid. 106 | */ 107 | public abstract void remove() throws InvalidNodeException; 108 | 109 | } 110 | -------------------------------------------------------------------------------- /hw/hw5/list/SListNode.java: -------------------------------------------------------------------------------- 1 | /* SListNode.java */ 2 | 3 | package list; 4 | 5 | /** 6 | * An SListNode is a mutable node in an SList (singly-linked list). 7 | **/ 8 | 9 | public class SListNode extends ListNode { 10 | 11 | /** 12 | * (inherited) item references the item stored in the current node. 13 | * (inherited) myList references the List that contains this node. 14 | * next references the next node in the SList. 15 | * 16 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 17 | **/ 18 | 19 | protected SListNode next; 20 | 21 | /** 22 | * SListNode() constructor. 23 | * @param i the item to store in the node. 24 | * @param l the list this node is in. 25 | * @param n the node following this node. 26 | */ 27 | SListNode(Object i, SList l, SListNode n) { 28 | item = i; 29 | myList = l; 30 | next = n; 31 | } 32 | 33 | /** 34 | * next() returns the node following this node. If this node is invalid, 35 | * throws an exception. 36 | * 37 | * @return the node following this node. 38 | * @exception InvalidNodeException if this node is not valid. 39 | * 40 | * Performance: runs in O(1) time. 41 | */ 42 | public ListNode next() throws InvalidNodeException { 43 | if (!isValidNode()) { 44 | throw new InvalidNodeException("next() called on invalid node"); 45 | } 46 | if (next == null) { 47 | // Create an invalid node. 48 | SListNode node = ((SList) myList).newNode(null, null); 49 | node.myList = null; 50 | return node; 51 | } else { 52 | return next; 53 | } 54 | } 55 | 56 | /** 57 | * prev() returns the node preceding this node. If this node is invalid, 58 | * throws an exception. 59 | * 60 | * @param node the node whose predecessor is sought. 61 | * @return the node preceding this node. 62 | * @exception InvalidNodeException if this node is not valid. 63 | * 64 | * Performance: runs in O(this.size) time. 65 | */ 66 | public ListNode prev() throws InvalidNodeException { 67 | if (!isValidNode()) { 68 | throw new InvalidNodeException("prev() called on invalid node"); 69 | } 70 | SListNode prev = ((SList) myList).head; 71 | if (prev == this) { 72 | // Create an invalid node. 73 | prev = ((SList) myList).newNode(null, null); 74 | prev.myList = null; 75 | } else { 76 | while (prev.next != this) { 77 | prev = prev.next; 78 | } 79 | } 80 | return prev; 81 | } 82 | 83 | /** 84 | * insertAfter() inserts an item immediately following this node. If this 85 | * node is invalid, throws an exception. 86 | * 87 | * @param item the item to be inserted. 88 | * @exception InvalidNodeException if this node is not valid. 89 | * 90 | * Performance: runs in O(1) time. 91 | */ 92 | public void insertAfter(Object item) throws InvalidNodeException { 93 | if (!isValidNode()) { 94 | throw new InvalidNodeException("insertAfter() called on invalid node"); 95 | } 96 | SListNode newNode = ((SList) myList).newNode(item, next); 97 | if (next == null) { 98 | ((SList) myList).tail = newNode; 99 | } 100 | next = newNode; 101 | myList.size++; 102 | } 103 | 104 | /** 105 | * insertBefore() inserts an item immediately preceding this node. If this 106 | * node is invalid, throws an exception. 107 | * 108 | * @param item the item to be inserted. 109 | * @exception InvalidNodeException if this node is not valid. 110 | * 111 | * Performance: runs in O(this.size) time. 112 | */ 113 | public void insertBefore(Object item) throws InvalidNodeException { 114 | if (!isValidNode()) { 115 | throw new InvalidNodeException("insertBefore() called on invalid node"); 116 | } 117 | SListNode newNode = ((SList) myList).newNode(item, this); 118 | if (this == ((SList) myList).head) { 119 | ((SList) myList).head = newNode; 120 | } else { 121 | SListNode prev = (SListNode) prev(); 122 | prev.next = newNode; 123 | } 124 | myList.size++; 125 | } 126 | 127 | /** 128 | * remove() removes this node from its SList. If this node is invalid, 129 | * throws an exception. 130 | * 131 | * @exception InvalidNodeException if this node is not valid. 132 | * 133 | * Performance: runs in O(this.size) time. 134 | */ 135 | public void remove() throws InvalidNodeException { 136 | if (!isValidNode()) { 137 | throw new InvalidNodeException("remove() called on invalid node"); 138 | } 139 | if (this == ((SList) myList).head) { 140 | ((SList) myList).head = next; 141 | if (next == null) { 142 | ((SList) myList).tail = null; 143 | } 144 | } else { 145 | SListNode prev = (SListNode) prev(); 146 | prev.next = next; 147 | if (next == null) { 148 | ((SList) myList).tail = prev; 149 | } 150 | } 151 | myList.size--; 152 | 153 | // Make this node an invalid node, so it cannot be used to corrupt myList. 154 | myList = null; 155 | // Set other reference to null to improve garbage collection. 156 | next = null; 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /hw/hw6/Homework6Test.java: -------------------------------------------------------------------------------- 1 | /* Homework6Test.java */ 2 | 3 | import dict.*; 4 | 5 | /** 6 | * Initializes a hash table, then stocks it with random SimpleBoards. 7 | **/ 8 | 9 | public class Homework6Test { 10 | 11 | /** 12 | * Generates a random 8 x 8 SimpleBoard. 13 | **/ 14 | 15 | private static SimpleBoard randomBoard() { 16 | SimpleBoard board = new SimpleBoard(); 17 | for (int y = 0; y < 8; y++) { 18 | for (int x = 0; x < 8; x++) { 19 | double fval = Math.random() * 12; 20 | int value = (int) fval; 21 | board.setElementAt(x, y, value); 22 | } 23 | } 24 | return board; 25 | } 26 | 27 | /** 28 | * Empties the given table, then inserts "numBoards" boards into the table. 29 | * @param table is the hash table to be initialized. 30 | * @param numBoards is the number of random boards to place in the table. 31 | **/ 32 | 33 | public static void initTable(HashTableChained table, int numBoards) { 34 | table.makeEmpty(); 35 | for (int i = 0; i < numBoards; i++) { 36 | table.insert(randomBoard(), new Integer(i)); 37 | } 38 | } 39 | 40 | /** 41 | * Creates a hash table and stores a certain number of SimpleBoards in it. 42 | * The number is 100 by default, but you can specify any number at the 43 | * command line. For example: 44 | * 45 | * java Homework6Test 12000 46 | **/ 47 | 48 | public static void main(String[] args) { 49 | int numBoards; 50 | 51 | if (args.length == 0) { 52 | numBoards = 100; 53 | } else { 54 | numBoards = Integer.parseInt(args[0]); 55 | } 56 | HashTableChained table = new HashTableChained(numBoards); 57 | initTable(table, numBoards); 58 | 59 | // To test your hash function, add a method to your HashTableChained class 60 | // that counts the number of collisions--or better yet, also prints 61 | // a histograph of the number of entries in each bucket. Call this method 62 | // from here. 63 | System.out.println("number of buckets is "+table.length+",number of entries is "+table.size); 64 | System.out.println(table.toString()); 65 | System.out.println("Expect collision:"+table.collision()); 66 | System.out.println("Real collision:"+table.sizeDup); 67 | 68 | numBoards = 200; 69 | table = new HashTableChained(numBoards); 70 | initTable(table, numBoards); 71 | System.out.println("number of buckets is "+table.length+",number of entries is "+table.size); 72 | System.out.println(table.toString()); 73 | System.out.println("Expected collision:"+table.collision()); 74 | System.out.println("Real collision:"+table.sizeDup); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /hw/hw6/SimpleBoard.java: -------------------------------------------------------------------------------- 1 | /* SimpleBoard.java */ 2 | 3 | /** 4 | * Simple class that implements an 8x8 game board with three possible values 5 | * for each cell: 0, 1 or 2. 6 | * 7 | * DO NOT CHANGE ANY PROTOTYPES IN THIS FILE. 8 | **/ 9 | 10 | public class SimpleBoard { 11 | private final static int DIMENSION = 8; 12 | private int[][] grid; 13 | 14 | /** 15 | * Invariants: 16 | * (1) grid.length == DIMENSION. 17 | * (2) for all 0 <= i < DIMENSION, grid[i].length == DIMENSION. 18 | * (3) for all 0 <= i, j < DIMENSION, grid[i][j] >= 0 and grid[i][j] <= 2. 19 | **/ 20 | 21 | /** 22 | * Construct a new board in which all cells are zero. 23 | */ 24 | 25 | public SimpleBoard() { 26 | grid = new int[DIMENSION][DIMENSION]; 27 | } 28 | 29 | /** 30 | * Set the cell (x, y) in the board to the given value mod 3. 31 | * @param value to which the element should be set (normally 0, 1, or 2). 32 | * @param x is the x-index. 33 | * @param y is the y-index. 34 | * @exception ArrayIndexOutOfBoundsException is thrown if an invalid index 35 | * is given. 36 | **/ 37 | 38 | public void setElementAt(int x, int y, int value) { 39 | grid[x][y] = value % 3; 40 | if (grid[x][y] < 0) { 41 | grid[x][y] = grid[x][y] + 3; 42 | } 43 | } 44 | 45 | /** 46 | * Get the valued stored in cell (x, y). 47 | * @param x is the x-index. 48 | * @param y is the y-index. 49 | * @return the stored value (between 0 and 2). 50 | * @exception ArrayIndexOutOfBoundsException is thrown if an invalid index 51 | * is given. 52 | */ 53 | 54 | public int elementAt(int x, int y) { 55 | return grid[x][y]; 56 | } 57 | 58 | /** 59 | * Returns true if "this" SimpleBoard and "board" have identical values in 60 | * every cell. 61 | * @param board is the second SimpleBoard. 62 | * @return true if the boards are equal, false otherwise. 63 | */ 64 | 65 | public boolean equals(Object board) { 66 | // Replace the following line with your solution. Be sure to return false 67 | // (rather than throwing a ClassCastException) if "board" is not 68 | // a SimpleBoard. 69 | if(board instanceof SimpleBoard){ 70 | for(int i = 0; i < DIMENSION; i++) 71 | for(int j = 0; j < DIMENSION; j++){ 72 | if(this.grid[i][j] != ((SimpleBoard)board).grid[i][j]) return false; 73 | } 74 | return true; 75 | }else{ 76 | return false; 77 | } 78 | 79 | } 80 | 81 | /** 82 | * Returns a hash code for this SimpleBoard. 83 | * @return a number between Integer.MIN_VALUE and Integer.MAX_VALUE. 84 | */ 85 | 86 | public int hashCode() { 87 | // Replace the following line with your solution. 88 | int code = 0; 89 | for(int i = 0; i < DIMENSION; i++) 90 | for(int j = 0; j < DIMENSION; j++){ 91 | code = code*3 + this.grid[i][j]; 92 | } 93 | return code; 94 | } 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /hw/hw6/dict/Dictionary.java: -------------------------------------------------------------------------------- 1 | /* Dictionary.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * An interface for (unordered) dictionary ADTs. 7 | * 8 | * DO NOT CHANGE THIS FILE. 9 | **/ 10 | 11 | public interface Dictionary { 12 | 13 | /** 14 | * Returns the number of entries stored in the dictionary. Entries with 15 | * the same key (or even the same key and value) each still count as 16 | * a separate entry. 17 | * @return number of entries in the dictionary. 18 | **/ 19 | 20 | public int size(); 21 | 22 | /** 23 | * Tests if the dictionary is empty. 24 | * 25 | * @return true if the dictionary has no entries; false otherwise. 26 | **/ 27 | 28 | public boolean isEmpty(); 29 | 30 | /** 31 | * Create a new Entry object referencing the input key and associated value, 32 | * and insert the entry into the dictionary. Return a reference to the new 33 | * entry. Multiple entries with the same key (or even the same key and 34 | * value) can coexist in the dictionary. 35 | * 36 | * @param key the key by which the entry can be retrieved. 37 | * @param value an arbitrary object. 38 | * @return an entry containing the key and value. 39 | **/ 40 | 41 | public Entry insert(Object key, Object value); 42 | 43 | /** 44 | * Search for an entry with the specified key. If such an entry is found, 45 | * return it; otherwise return null. If several entries have the specified 46 | * key, choose one arbitrarily and return it. 47 | * 48 | * @param key the search key. 49 | * @return an entry containing the key and an associated value, or null if 50 | * no entry contains the specified key. 51 | **/ 52 | 53 | public Entry find(Object key); 54 | 55 | /** 56 | * Remove an entry with the specified key. If such an entry is found, 57 | * remove it from the table and return it; otherwise return null. 58 | * If several entries have the specified key, choose one arbitrarily, then 59 | * remove and return it. 60 | * 61 | * @param key the search key. 62 | * @return an entry containing the key and an associated value, or null if 63 | * no entry contains the specified key. 64 | */ 65 | 66 | public Entry remove(Object key); 67 | 68 | /** 69 | * Remove all entries from the dictionary. 70 | */ 71 | 72 | public void makeEmpty(); 73 | 74 | } 75 | -------------------------------------------------------------------------------- /hw/hw6/dict/Entry.java: -------------------------------------------------------------------------------- 1 | /* Entry.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * A class for dictionary entries. 7 | * 8 | * DO NOT CHANGE THIS FILE. It is part of the interface of the 9 | * Dictionary ADT. 10 | **/ 11 | 12 | public class Entry { 13 | 14 | protected Object key; 15 | protected Object value; 16 | 17 | public Object key() { 18 | return key; 19 | } 20 | 21 | public Object value() { 22 | return value; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /hw/hw6/list/SList.java: -------------------------------------------------------------------------------- 1 | /* SList.java */ 2 | package list; 3 | 4 | /** 5 | * The SList class is a singly-linked implementation of the linked list 6 | * abstraction. SLists are mutable data structures, which can grow at either 7 | * end. 8 | * 9 | * @author Kathy Yelick and Jonathan Shewchuk 10 | **/ 11 | 12 | public class SList { 13 | 14 | private SListNode head; 15 | private int size; 16 | 17 | /** 18 | * SList() constructs an empty list. 19 | **/ 20 | 21 | public SList() { 22 | size = 0; 23 | head = null; 24 | } 25 | 26 | /** 27 | * isEmpty() indicates whether the list is empty. 28 | * @return true if the list is empty, false otherwise. 29 | **/ 30 | 31 | public boolean isEmpty() { 32 | return size == 0; 33 | } 34 | 35 | /** 36 | * length() returns the length of this list. 37 | * @return the length of this list. 38 | **/ 39 | 40 | public int length() { 41 | return size; 42 | } 43 | 44 | /** 45 | * insertFront() inserts item "obj" at the beginning of this list. 46 | * @param obj the item to be inserted. 47 | **/ 48 | 49 | public void insertFront(Object obj) { 50 | head = new SListNode(obj, head); 51 | size++; 52 | } 53 | 54 | /** 55 | * insertEnd() inserts item "obj" at the end of this list. 56 | * @param obj the item to be inserted. 57 | **/ 58 | 59 | public void insertEnd(Object obj) { 60 | if (head == null) { 61 | head = new SListNode(obj); 62 | } else { 63 | SListNode node = head; 64 | while (node.next != null) { 65 | node = node.next; 66 | } 67 | node.next = new SListNode(obj); 68 | } 69 | size++; 70 | } 71 | 72 | public void remove(int position){ 73 | if(position <= size){ 74 | SListNode node = head; 75 | if(position == 1){ 76 | node = null; 77 | }else if(position == 2){ 78 | node.next = node.next.next; 79 | }else{ 80 | for(int i=1; i<= position-2; i++){ 81 | node = node.next; 82 | } 83 | node.next = node.next.next; 84 | } 85 | 86 | } 87 | } 88 | 89 | public Object front(){ 90 | if(size == 0) return null; 91 | return head; 92 | } 93 | 94 | 95 | /** 96 | * toString() converts the list to a String. 97 | * @return a String representation of the list. 98 | **/ 99 | 100 | public String toString() { 101 | // int i; 102 | Object obj; 103 | String result = "[ "; 104 | 105 | SListNode cur = head; 106 | 107 | while (cur != null) { 108 | obj = cur.item; 109 | result = result + obj.toString() + " "; 110 | cur = cur.next; 111 | } 112 | result = result + "]"; 113 | return result; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /hw/hw6/list/SListNode.java: -------------------------------------------------------------------------------- 1 | /* SListNode.java */ 2 | package list; 3 | 4 | /** 5 | * SListNode is a class used internally by the SList class. An SList object 6 | * is a singly-linked list, and an SListNode is a node of a singly-linked 7 | * list. Each SListNode has two references: one to an object, and one to 8 | * the next node in the list. 9 | * 10 | * @author Kathy Yelick and Jonathan Shewchuk 11 | */ 12 | 13 | public class SListNode { 14 | public Object item; 15 | public SListNode next; 16 | 17 | 18 | /** 19 | * SListNode() (with two parameters) constructs a list node referencing the 20 | * item "obj", whose next list node is to be "next". 21 | */ 22 | 23 | public SListNode(Object obj, SListNode next) { 24 | item = obj; 25 | this.next = next; 26 | } 27 | 28 | /** 29 | * SListNode() (with one parameter) constructs a list node referencing the 30 | * item "obj". 31 | */ 32 | 33 | public SListNode(Object obj) { 34 | this(obj, null); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /hw/hw7/dict/IntDictionary.java: -------------------------------------------------------------------------------- 1 | /* IntDictionary.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * An IntDictionary is a mutable ordered dictionary ADT. Each item is an int 7 | * key; there are no additional values or objects associated with the key. 8 | * 9 | * DO NOT CHANGE THIS FILE. 10 | * 11 | * @author Jonathan Shewchuk 12 | */ 13 | 14 | public abstract class IntDictionary { 15 | 16 | /** 17 | * size is the number of items in the dictionary. 18 | **/ 19 | 20 | protected int size; 21 | 22 | /** 23 | * isEmpty() returns true if this IntDictionary is empty, false otherwise. 24 | * 25 | * @return true if this IntDictionary is empty, false otherwise. 26 | * 27 | * Performance: runs in O(1) time. 28 | **/ 29 | public boolean isEmpty() { 30 | return size == 0; 31 | } 32 | 33 | /** 34 | * size() returns the size of this IntDictionary. 35 | * 36 | * @return the size of this IntDictionary. 37 | * 38 | * Performance: runs in O(1) time. 39 | **/ 40 | public int size() { 41 | return size; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /hw/hw7/dict/Tree234Node.java: -------------------------------------------------------------------------------- 1 | /* Tree234Node.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * A Tree234Node is a node in a 2-3-4 tree (Tree234 class). 7 | * 8 | * DO NOT CHANGE ANYTHING IN THIS FILE. 9 | * You may add helper methods and additional constructors, though. 10 | **/ 11 | class Tree234Node { 12 | 13 | /** 14 | * keys is the number of keys in this node. Always 1, 2, or 3. 15 | * key1 through key3 are the keys of this node. If keys == 1, the value 16 | * of key2 doesn't matter. If keys < 3, the value of key3 doesn't matter. 17 | * parent is this node's parent; null if this is the root. 18 | * child1 through child4 are the children of this node. If this is a leaf 19 | * node, they must all be set to null. If this node has no third and/or 20 | * fourth child, child3 and/or child4 must be set to null. 21 | **/ 22 | int keys; 23 | int key1; 24 | int key2; 25 | int key3; 26 | Tree234Node parent; 27 | Tree234Node child1; 28 | Tree234Node child2; 29 | Tree234Node child3; 30 | Tree234Node child4; 31 | 32 | Tree234Node(Tree234Node p, int key) { 33 | keys = 1; 34 | key1 = key; 35 | parent = p; 36 | child1 = null; 37 | child2 = null; 38 | child3 = null; 39 | child4 = null; 40 | } 41 | public boolean isLeaf() { 42 | return child1 == null && child2 == null && child3 == null && child4 == null; 43 | } 44 | 45 | /** 46 | * toString() recursively prints this Tree234Node and its descendants as 47 | * a String. Each node is printed in the form such as (for a 3-key node) 48 | * 49 | * (child1)key1(child2)key2(child3)key3(child4) 50 | * 51 | * where each child is a recursive call to toString, and null children 52 | * are printed as a space with no parentheses. Here's an example. 53 | * ((1)7(11 16)22(23)28(37 49))50((60)84(86 95 100)) 54 | * 55 | * DO NOT CHANGE THIS METHOD. 56 | **/ 57 | public String toString() { 58 | String s = ""; 59 | 60 | if (child1 != null) { 61 | s = "(" + child1.toString() + ")"; 62 | } 63 | s = s + key1; 64 | if (child2 != null) { 65 | s = s + "(" + child2.toString() + ")"; 66 | } else if (keys > 1) { 67 | s = s + " "; 68 | } 69 | if (keys > 1) { 70 | s = s + key2; 71 | if (child3 != null) { 72 | s = s + "(" + child3.toString() + ")"; 73 | } else if (keys > 2) { 74 | s = s + " "; 75 | } 76 | } 77 | if (keys > 2) { 78 | s = s + key3; 79 | if (child4 != null) { 80 | s = s + "(" + child4.toString() + ")"; 81 | } 82 | } 83 | return s; 84 | } 85 | 86 | /** 87 | * printSubtree() recursively prints this Tree234Node and its descendants as 88 | * a tree (albeit sideways). 89 | * 90 | * You're welcome to change this method if you like. It won't be tested. 91 | **/ 92 | public void printSubtree(int spaces) { 93 | if (child4 != null) { 94 | child4.printSubtree(spaces + 5); 95 | } 96 | if (keys == 3) { 97 | for (int i = 0; i < spaces; i++) { 98 | System.out.print(" "); 99 | } 100 | System.out.println(key3); 101 | } 102 | 103 | if (child3 != null) { 104 | child3.printSubtree(spaces + 5); 105 | } 106 | if (keys > 1) { 107 | for (int i = 0; i < spaces; i++) { 108 | System.out.print(" "); 109 | } 110 | System.out.println(key2); 111 | } 112 | 113 | if (child2 != null) { 114 | child2.printSubtree(spaces + 5); 115 | } 116 | for (int i = 0; i < spaces; i++) { 117 | System.out.print(" "); 118 | } 119 | System.out.println(key1); 120 | 121 | if (child1 != null) { 122 | child1.printSubtree(spaces + 5); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /hw/hw8/Timer.java: -------------------------------------------------------------------------------- 1 | /* Timer.java */ 2 | 3 | /** 4 | * Implements a simple stopwatch/timer class based on wall-clock time. 5 | **/ 6 | 7 | /** 8 | * RUNNING() == true <==> start() called with no corresponding 9 | * call to stop() 10 | * 11 | * All times are given in units of msec. 12 | **/ 13 | public class Timer { 14 | 15 | private boolean running; 16 | private long tStart; 17 | private long tFinish; 18 | private long tAccum; 19 | 20 | /** 21 | * Initializes Timer to 0 msec 22 | **/ 23 | public Timer() { 24 | reset(); 25 | } 26 | 27 | /** 28 | * Starts the timer. Accumulates time across multiple calls to start. 29 | **/ 30 | public void start() { 31 | running = true; 32 | tStart = System.currentTimeMillis(); 33 | tFinish = tStart; 34 | } 35 | 36 | /** 37 | * Stops the timer. returns the time elapsed since the last matching call 38 | * to start(), or zero if no such matching call was made. 39 | **/ 40 | public long stop() { 41 | tFinish = System.currentTimeMillis(); 42 | if (running) { 43 | running = false; 44 | 45 | long diff = tFinish - tStart; 46 | tAccum += diff; 47 | return diff; 48 | } 49 | return 0; 50 | } 51 | 52 | /** 53 | * if RUNNING() ==> returns the time since last call to start() 54 | * if !RUNNING() ==> returns total elapsed time 55 | **/ 56 | public long elapsed() { 57 | if (running) { 58 | return System.currentTimeMillis() - tStart; 59 | } 60 | 61 | return tAccum; 62 | } 63 | 64 | /** 65 | * Stops timing, if currently RUNNING(); resets 66 | * accumulated time to 0. 67 | */ 68 | public void reset() { 69 | running = false; 70 | tStart = 0; 71 | tFinish = 0; 72 | tAccum = 0; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /hw/hw8/list/LinkedQueue.java: -------------------------------------------------------------------------------- 1 | /* LinkedQueue.java */ 2 | 3 | package list; 4 | 5 | public class LinkedQueue implements Queue { 6 | 7 | private SListNode head; 8 | private SListNode tail; 9 | private int size; 10 | 11 | /** 12 | * LinkedQueue() constructs an empty queue. 13 | **/ 14 | public LinkedQueue() { 15 | size = 0; 16 | head = null; 17 | tail = null; 18 | } 19 | 20 | /** 21 | * size() returns the size of this Queue. 22 | * @return the size of this Queue. 23 | * Performance: runs in O(1) time. 24 | **/ 25 | public int size() { 26 | return size; 27 | } 28 | 29 | /** 30 | * isEmpty() returns true if this Queue is empty, false otherwise. 31 | * @return true if this Queue is empty, false otherwise. 32 | * Performance: runs in O(1) time. 33 | **/ 34 | public boolean isEmpty() { 35 | return size == 0; 36 | } 37 | 38 | /** 39 | * enqueue() inserts an object at the end of the Queue. 40 | * @param item the item to be enqueued. 41 | **/ 42 | public void enqueue(Object item) { 43 | if (head == null) { 44 | head = new SListNode(item); 45 | tail = head; 46 | } else { 47 | tail.next = new SListNode(item); 48 | tail = tail.next; 49 | } 50 | size++; 51 | } 52 | 53 | /** 54 | * dequeue() removes and returns the object at the front of the Queue. 55 | * @return the item dequeued. 56 | * @throws a QueueEmptyException if the Queue is empty. 57 | **/ 58 | public Object dequeue() throws QueueEmptyException { 59 | if (head == null) { 60 | throw new QueueEmptyException(); 61 | } else { 62 | Object o = head.item; 63 | head = head.next; 64 | size--; 65 | if (size == 0) { 66 | tail = null; 67 | } 68 | return o; 69 | } 70 | } 71 | 72 | /** 73 | * front() returns the object at the front of the Queue. 74 | * @return the item at the front of the Queue. 75 | * @throws a QueueEmptyException if the Queue is empty. 76 | **/ 77 | public Object front() throws QueueEmptyException { 78 | if (head == null) { 79 | throw new QueueEmptyException(); 80 | } else { 81 | return head.item; 82 | } 83 | } 84 | 85 | /** 86 | * 87 | * nth() returns the nth item in this LinkedQueue. 88 | * Items in the queue are numbered from 1. 89 | * @param n the number of the item to return. 90 | */ 91 | public Object nth(int n) { 92 | SListNode node = head; 93 | for (; n > 1; n--) { 94 | node = node.next; 95 | } 96 | return node.item; 97 | } 98 | 99 | /** 100 | * append() appends the contents of q onto the end of this LinkedQueue. 101 | * On completion, q is empty. 102 | * @param q the LinkedQueue whose contents should be appended onto this 103 | * LinkedQueue. 104 | **/ 105 | public void append(LinkedQueue q) { 106 | if (head == null) { 107 | head = q.head; 108 | } else { 109 | tail.next = q.head; 110 | } 111 | if (q.head != null) { 112 | tail = q.tail; 113 | } 114 | size = size + q.size; 115 | q.head = null; 116 | q.tail = null; 117 | q.size = 0; 118 | } 119 | 120 | /** 121 | * toString() converts this queue to a String. 122 | **/ 123 | public String toString() { 124 | String out = "[ "; 125 | try { 126 | for (int i = 0; i < size(); i++) { 127 | out = out + front() + " "; 128 | enqueue(dequeue()); 129 | } 130 | } catch (QueueEmptyException uf) { 131 | System.err.println("Error: attempt to dequeue from empty queue."); 132 | } 133 | return out + "]"; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /hw/hw8/list/Queue.java: -------------------------------------------------------------------------------- 1 | /* Queue.java */ 2 | 3 | package list; 4 | 5 | public interface Queue { 6 | 7 | /** 8 | * size() returns the size of this Queue. 9 | * @return the size of this Queue. 10 | * Performance: runs in O(1) time. 11 | **/ 12 | public int size(); 13 | 14 | /** 15 | * isEmpty() returns true if this Queue is empty, false otherwise. 16 | * @return true if this Queue is empty, false otherwise. 17 | * Performance: runs in O(1) time. 18 | **/ 19 | public boolean isEmpty(); 20 | 21 | /** 22 | * enqueue() inserts an object at the end of the Queue. 23 | * @param item the item to be enqueued. 24 | **/ 25 | public void enqueue(Object item); 26 | 27 | /** 28 | * dequeue() removes and returns the object at the front of the Queue. 29 | * @return the item dequeued. 30 | * @throws a QueueEmptyException if the Queue is empty. 31 | **/ 32 | public Object dequeue() throws QueueEmptyException; 33 | 34 | /** 35 | * front() returns the object at the front of the Queue. 36 | * @return the item at the front of the Queue. 37 | * @throws a QueueEmptyException if the Queue is empty. 38 | **/ 39 | public Object front() throws QueueEmptyException; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /hw/hw8/list/QueueEmptyException.java: -------------------------------------------------------------------------------- 1 | /* QueueEmptyException.java */ 2 | 3 | package list; 4 | 5 | public class QueueEmptyException extends Exception { 6 | 7 | public QueueEmptyException() { 8 | super(); 9 | } 10 | 11 | public QueueEmptyException(String s) { 12 | super(s); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /hw/hw8/list/SListNode.java: -------------------------------------------------------------------------------- 1 | /* SListNode.java */ 2 | 3 | package list; 4 | 5 | /** 6 | * SListNode is a class used internally by the SList class. An SList object 7 | * is a singly-linked list, and an SListNode is a node of a singly-linked 8 | * list. Each SListNode has two references: one to an object, and one to 9 | * the next node in the list. 10 | */ 11 | 12 | class SListNode { 13 | Object item; 14 | SListNode next; 15 | 16 | /** 17 | * SListNode() (with one parameter) constructs a list node referencing the 18 | * item "obj". 19 | */ 20 | 21 | SListNode(Object obj) { 22 | item = obj; 23 | next = null; 24 | } 25 | 26 | /** 27 | * SListNode() (with two parameters) constructs a list node referencing the 28 | * item "obj", whose next list node is to be "next". 29 | */ 30 | 31 | SListNode(Object obj, SListNode next) { 32 | item = obj; 33 | this.next = next; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /hw/hw9/set/DisjointSets.java: -------------------------------------------------------------------------------- 1 | /* DisjointSets.java */ 2 | 3 | package set; 4 | 5 | /** 6 | * A disjoint sets ADT. Performs union-by-size and path compression. 7 | * Implemented using arrays. There is no error checking whatsoever. 8 | * By adding your own error-checking, you might save yourself a lot of time 9 | * finding bugs in your application code for Project 3 and Homework 9. 10 | * Without error-checking, expect bad things to happen if you try to unite 11 | * two elements that are not roots of their respective sets, or are not 12 | * distinct. 13 | * 14 | * Elements are represented by ints, numbered from zero. 15 | **/ 16 | 17 | public class DisjointSets { 18 | 19 | private int[] array; 20 | 21 | /** 22 | * Construct a disjoint sets object. 23 | * 24 | * @param numElements the initial number of elements--also the initial 25 | * number of disjoint sets, since every element is initially in its own set. 26 | **/ 27 | public DisjointSets(int numElements) { 28 | array = new int [numElements]; 29 | for (int i = 0; i < array.length; i++) { 30 | array[i] = -1; 31 | } 32 | } 33 | 34 | /** 35 | * union() unites two disjoint sets into a single set. A union-by-size 36 | * heuristic is used to choose the new root. This method will corrupt 37 | * the data structure if root1 and root2 are not roots of their respective 38 | * sets, or if they're identical. 39 | * 40 | * @param root1 the root of the first set. 41 | * @param root2 the root of the other set. 42 | **/ 43 | public void union(int root1, int root2) { 44 | if (array[root2] < array[root1]) { // root2 has larger tree 45 | array[root2] += array[root1]; // update # of items in root2's tree 46 | array[root1] = root2; // make root2 new root 47 | } else { // root1 has equal or larger tree 48 | array[root1] += array[root2]; // update # of items in root1's tree 49 | array[root2] = root1; // make root1 new root 50 | } 51 | } 52 | 53 | /** 54 | * find() finds the (int) name of the set containing a given element. 55 | * Performs path compression along the way. 56 | * 57 | * @param x the element sought. 58 | * @return the set containing x. 59 | **/ 60 | public int find(int x) { 61 | if (array[x] < 0) { 62 | return x; // x is the root of the tree; return it 63 | } else { 64 | // Find out who the root is; compress path by making the root x's parent. 65 | array[x] = find(array[x]); 66 | return array[x]; // Return the root 67 | } 68 | } 69 | 70 | /** 71 | * main() is test code. All the find()s on the same output line should be 72 | * identical. 73 | **/ 74 | public static void main(String[] args) { 75 | int NumElements = 128; 76 | int NumInSameSet = 16; 77 | 78 | DisjointSets s = new DisjointSets(NumElements); 79 | int set1, set2; 80 | 81 | for (int k = 1; k < NumInSameSet; k *= 2) { 82 | for (int j = 0; j + k < NumElements; j += 2 * k) { 83 | set1 = s.find(j); 84 | set2 = s.find(j + k); 85 | s.union(set1, set2); 86 | } 87 | } 88 | 89 | for (int i = 0; i < NumElements; i++) { 90 | System.out.print(s.find(i) + "*"); 91 | if (i % NumInSameSet == NumInSameSet - 1) { 92 | System.out.println(); 93 | } 94 | } 95 | System.out.println(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /lab/lab1/Names.java: -------------------------------------------------------------------------------- 1 | /* Names.java */ 2 | 3 | import java.io.*; 4 | 5 | /** The Names class provides a single function, main, that will 6 | * perform various manipulations of the name John Fitzgerald Kennedy. 7 | * This is a modification of the program on page 43 of Arnow and Weiss. 8 | */ 9 | 10 | class Names { 11 | 12 | /** Performs various string operations on the name John Fitzgerald Kennedy. 13 | * @param arg is not used. 14 | */ 15 | public static void main(String arg[]) { 16 | String first = "John"; 17 | String middle = "Fitzgerald"; 18 | String last = "Kennedy"; 19 | String initials; 20 | String firstInit, middleInit, lastInit; 21 | 22 | firstInit = first.substring(0,1); 23 | middleInit = middle.substring(0,1); 24 | lastInit = last.substring(0,1); 25 | initials = firstInit.concat(middleInit); 26 | initials = initials.concat(lastInit); 27 | 28 | System.out.println(); 29 | System.out.println(first + " " + middle + " " + last + " "); 30 | System.out.println(initials); 31 | System.out.println(last + ", " + first + " " + middle); 32 | System.out.println(last + ", " + first + " " + middleInit +"."); 33 | System.out.println(first.toUpperCase() + " " + last.toUpperCase()); 34 | 35 | System.out.println(first + " equals john is " + first.equals("john")); 36 | System.out.println(first + " equals john (ignoring case) is " 37 | + first.equalsIgnoreCase("john")); 38 | System.out.println("The character at index 3 in " + middle + " is " + 39 | middle.substring(1,3)); 40 | System.out.println("The index of \"gerald\" within " + middle + " is " + 41 | middle.indexOf("gerald")); 42 | System.out.println("The index of \"gerald\" within " + last + " is " + 43 | last.indexOf("gerald")); 44 | 45 | System.out.println(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lab/lab10/tree/InvalidNodeException.java: -------------------------------------------------------------------------------- 1 | /* InvalidNodeException.java */ 2 | 3 | package tree; 4 | 5 | /** 6 | * Implements an Exception that signals an attempt to use an invalid ListNode. 7 | */ 8 | 9 | public class InvalidNodeException extends Exception { 10 | protected InvalidNodeException() { 11 | super(); 12 | } 13 | 14 | protected InvalidNodeException(String s) { 15 | super(s); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lab/lab10/tree/SibTreeNode.java: -------------------------------------------------------------------------------- 1 | /* SibTreeNode.java */ 2 | 3 | package tree; 4 | 5 | /** 6 | * A SibTreeNode object is a node in a SibTree (sibling-based general tree). 7 | * @author Jonathan Shewchuk 8 | */ 9 | 10 | class SibTreeNode extends TreeNode { 11 | 12 | /** 13 | * (inherited) item references the item stored in this node. 14 | * (inherited) valid is true if and only if this is a valid node in some 15 | * Tree. 16 | * myTree references the Tree that contains this node. 17 | * parent references this node's parent node. 18 | * firstChild references this node's first (leftmost) child. 19 | * nextSibling references this node's next sibling. 20 | * 21 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 22 | */ 23 | 24 | /** 25 | * ADT implementation invariants: 26 | * 1) if valid == true, myTree != null. 27 | * 2) if valid == true, then this is a descendent of myTree.root. 28 | * 3) if valid == true, myTree satisfies all the invariants of a 29 | * SibTree (listed in SibTree.java). 30 | */ 31 | 32 | protected SibTree myTree; 33 | protected SibTreeNode parent; 34 | protected SibTreeNode firstChild; 35 | protected SibTreeNode nextSibling; 36 | 37 | /** 38 | * Construct a valid SibTreeNode referring to a given item. 39 | */ 40 | SibTreeNode(SibTree tree, Object item) { 41 | this.item = item; 42 | valid = true; 43 | myTree = tree; 44 | parent = null; 45 | firstChild = null; 46 | nextSibling = null; 47 | } 48 | 49 | /** 50 | * Construct an invalid SibTreeNode. 51 | */ 52 | SibTreeNode() { 53 | valid = false; 54 | } 55 | 56 | /** 57 | * children() returns the number of children of the node at this position. 58 | * WARNING: Does not run in constant time. Actually counts the kids. 59 | */ 60 | public int children() { 61 | if (isValidNode()) { 62 | int count = 0; 63 | SibTreeNode countNode = firstChild; 64 | while (countNode != null) { 65 | count++; 66 | countNode = countNode.nextSibling; 67 | } 68 | return count; 69 | } else { 70 | return 0; 71 | } 72 | } 73 | 74 | /** 75 | * parent() returns the parent TreeNode of this TreeNode. Throws an 76 | * exception if `this' is not a valid node. Returns an invalid TreeNode if 77 | * this node is the root. 78 | */ 79 | public TreeNode parent() throws InvalidNodeException { 80 | // REPLACE THE FOLLOWING LINE WITH YOUR SOLUTION TO PART I. 81 | if(!isValidNode()) throw new InvalidNodeException(); 82 | if(parent == null){ 83 | return new SibTreeNode(); 84 | }else{ 85 | return parent; 86 | } 87 | } 88 | 89 | /** 90 | * child() returns the cth child of this TreeNode. Throws an exception if 91 | * `this' is not a valid node. Returns an invalid TreeNode if there is no 92 | * cth child. 93 | */ 94 | public TreeNode child(int c) throws InvalidNodeException { 95 | if (isValidNode()) { 96 | if (c < 1) { 97 | return new SibTreeNode(); 98 | } 99 | SibTreeNode kid = firstChild; 100 | while ((kid != null) && (c > 1)) { 101 | kid = kid.nextSibling; 102 | c--; 103 | } 104 | if (kid == null) { 105 | return new SibTreeNode(); 106 | } else { 107 | return kid; 108 | } 109 | } else { 110 | throw new InvalidNodeException(); 111 | } 112 | } 113 | 114 | /** 115 | * nextSibling() returns the next sibling TreeNode to the right from this 116 | * TreeNode. Throws an exception if `this' is not a valid node. Returns 117 | * an invalid TreeNode if there is no sibling to the right of this node. 118 | */ 119 | public TreeNode nextSibling() throws InvalidNodeException { 120 | if (isValidNode()) { 121 | if (nextSibling == null) { 122 | return new SibTreeNode(); 123 | } else { 124 | return nextSibling; 125 | } 126 | } else { 127 | throw new InvalidNodeException(); 128 | } 129 | } 130 | 131 | /** 132 | * insertChild() inserts an item as the cth child of this node. Existing 133 | * children numbered c or higher are shifted one place to the right 134 | * to accommodate. If the current node has fewer than c children, 135 | * the new item is inserted as the last child. If c < 1, act as if c is 1. 136 | * 137 | * Throws an InvalidNodeException if "this" node is invalid. 138 | */ 139 | public void insertChild(Object item, int c) throws InvalidNodeException { 140 | // FILL IN YOUR SOLUTION TO PART II HERE. 141 | if(!isValidNode()) throw new InvalidNodeException(); 142 | SibTreeNode newNode = new SibTreeNode(myTree, item); 143 | newNode.parent = this; 144 | if(c <= 1){ 145 | newNode.nextSibling = this.firstChild; 146 | this.firstChild = newNode; 147 | }else{ 148 | int children = children(); 149 | if(c > children){ 150 | SibTreeNode lastNode = (SibTreeNode) child(children); 151 | lastNode.nextSibling = newNode; 152 | }else{ 153 | SibTreeNode node = (SibTreeNode) child(c-1); 154 | newNode.nextSibling = node.nextSibling; 155 | node.nextSibling = newNode; 156 | } 157 | } 158 | myTree.size++; 159 | } 160 | 161 | /** 162 | * removeLeaf() removes the node at the current position from the tree if 163 | * it is a leaf. Does nothing if `this' has one or more children. Throws 164 | * an exception if `this' is not a valid node. If 'this' has siblings to 165 | * its right, those siblings are all shifted left by one. 166 | */ 167 | public void removeLeaf() throws InvalidNodeException { 168 | // FILL IN YOUR SOLUTION TO PART III HERE. 169 | if(!isValidNode()) throw new InvalidNodeException(); 170 | if(children() <= 0){ 171 | if(this == myTree.root()){ 172 | myTree.root = null; 173 | }else{ 174 | SibTreeNode parent = (SibTreeNode) parent(); 175 | SibTreeNode node = (SibTreeNode) parent.firstChild; 176 | if(node == this){ 177 | parent.firstChild = (SibTreeNode) nextSibling; 178 | }else{ 179 | while(node.nextSibling !=this){ 180 | node = node.nextSibling; 181 | } 182 | node.nextSibling = nextSibling; 183 | } 184 | } 185 | valid = false; 186 | myTree.size--; 187 | } 188 | } 189 | 190 | } 191 | -------------------------------------------------------------------------------- /lab/lab10/tree/Tree.java: -------------------------------------------------------------------------------- 1 | /* Tree.java */ 2 | 3 | package tree; 4 | 5 | /** 6 | * A Tree is a mutable ADT for general trees (wherein a node can have any 7 | * number of children). 8 | * @author Jonathan Shewchuk 9 | */ 10 | 11 | public abstract class Tree { 12 | 13 | /** 14 | * size is the number of items in the tree. 15 | **/ 16 | 17 | protected int size; 18 | 19 | /** 20 | * isEmpty() returns true if this Tree is empty, false otherwise. 21 | * 22 | * @return true if this Tree is empty, false otherwise. 23 | * 24 | * Performance: runs in O(1) time. 25 | **/ 26 | public boolean isEmpty() { 27 | return size == 0; 28 | } 29 | 30 | /** 31 | * size() returns the size of this Tree. 32 | * 33 | * @return the size of this Tree. 34 | * 35 | * Performance: runs in O(1) time. 36 | **/ 37 | public int size() { 38 | return size; 39 | } 40 | 41 | /** 42 | * root() returns the root node, if one exists. Returns an invalid node if 43 | * the tree is empty. 44 | */ 45 | public abstract TreeNode root(); 46 | 47 | /** 48 | * insertRoot() inserts a node containing "item" at the root of the tree. 49 | * If a root already exists, it becomes a child of the new node. 50 | */ 51 | public abstract void insertRoot(Object item); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /lab/lab10/tree/TreeNode.java: -------------------------------------------------------------------------------- 1 | /* TreeNode.java */ 2 | 3 | package tree; 4 | 5 | /** 6 | * A TreeNode object is a mutable node in a tree. No implementation is 7 | * provided. 8 | * 9 | * DO NOT CHANGE THIS FILE. 10 | * @author Jonathan Shewchuk 11 | */ 12 | 13 | public abstract class TreeNode { 14 | 15 | /** 16 | * item references the item stored in this node. 17 | * valid is true if and only if this is a valid node in some Tree. 18 | * 19 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 20 | */ 21 | 22 | protected Object item; 23 | protected boolean valid; 24 | 25 | /** 26 | * isValidNode returns true if this node is valid; false otherwise. 27 | * 28 | * @return true if this node is valid; false otherwise. 29 | * 30 | * Performance: runs in O(1) time. 31 | */ 32 | public boolean isValidNode() { 33 | return valid; 34 | } 35 | 36 | /** 37 | * item() returns this node's item. If this node is invalid, 38 | * throws an exception. 39 | * 40 | * @return the item stored in this node. 41 | * 42 | * Performance: runs in O(1) time. 43 | */ 44 | public Object item() throws InvalidNodeException { 45 | if (isValidNode()) { 46 | return item; 47 | } else { 48 | throw new InvalidNodeException(); 49 | } 50 | } 51 | 52 | /** 53 | * setItem() sets this node's item to "item". If this node is invalid, 54 | * throws an exception. 55 | * 56 | * Performance: runs in O(1) time. 57 | */ 58 | public void setItem(Object item) throws InvalidNodeException { 59 | if (isValidNode()) { 60 | this.item = item; 61 | } else { 62 | throw new InvalidNodeException(); 63 | } 64 | } 65 | 66 | /** 67 | * children() returns the number of children of the node at this position. 68 | */ 69 | public abstract int children(); 70 | 71 | /** 72 | * parent() returns the parent TreeNode of this TreeNode. Throws an 73 | * exception if `this' is not a valid node. Returns an invalid TreeNode if 74 | * this node is the root. 75 | */ 76 | public abstract TreeNode parent() throws InvalidNodeException; 77 | 78 | /** 79 | * child() returns the cth child of this TreeNode. Throws an exception if 80 | * `this' is not a valid node. Returns an invalid TreeNode if there is no 81 | * cth child. 82 | */ 83 | public abstract TreeNode child(int c) throws InvalidNodeException; 84 | 85 | /** 86 | * nextSibling() returns the next sibling TreeNode to the right from this 87 | * TreeNode. Throws an exception if `this' is not a valid node. Returns 88 | * an invalid TreeNode if there is no sibling to the right of this node. 89 | */ 90 | public abstract TreeNode nextSibling() throws InvalidNodeException; 91 | 92 | /** 93 | * insertChild() inserts an item as the cth child of this node. Existing 94 | * children numbered c or higher are shifted one place to the right 95 | * to accommodate. If the current node has fewer than c children, 96 | * the new item is inserted as the last child. If c < 1, act as if c is 1. 97 | */ 98 | public abstract void insertChild(Object item, int c) throws 99 | InvalidNodeException; 100 | 101 | /** 102 | * removeLeaf() removes the node at the current position from the tree if 103 | * it is a leaf. Does nothing if `this' has one or more children. Throws 104 | * an exception if `this' is not a valid node. If 'this' has siblings to 105 | * its right, those siblings are all shifted left by one. 106 | */ 107 | public abstract void removeLeaf() throws InvalidNodeException; 108 | 109 | } 110 | -------------------------------------------------------------------------------- /lab/lab11/dict/BinaryTreeNode.java: -------------------------------------------------------------------------------- 1 | /* BinaryTreeNode.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * BinaryTreeNode represents a node in a binary tree. 7 | * 8 | * DO NOT CHANGE THIS FILE. 9 | **/ 10 | class BinaryTreeNode { 11 | 12 | /** 13 | * entry is a (key, value) pair stored in this node. 14 | * parent is the parent of this node. 15 | * leftChild and rightChild are the children of this node. 16 | **/ 17 | Entry entry; 18 | BinaryTreeNode parent; 19 | BinaryTreeNode leftChild, rightChild; 20 | 21 | /** 22 | * Construct a BinaryTreeNode with a specified entry; parent and children 23 | * are null. 24 | **/ 25 | BinaryTreeNode(Entry entry) { 26 | this(entry, null, null, null); 27 | } 28 | 29 | /** 30 | * Construct a BinaryTreeNode with a specified entry and parent; children 31 | * are null. 32 | **/ 33 | BinaryTreeNode(Entry entry, BinaryTreeNode parent) { 34 | this(entry, parent, null, null); 35 | } 36 | 37 | /** 38 | * Construct a BinaryTreeNode, specifying all four fields. 39 | **/ 40 | BinaryTreeNode(Entry entry, BinaryTreeNode parent, 41 | BinaryTreeNode left, BinaryTreeNode right) { 42 | this.entry = entry; 43 | this.parent = parent; 44 | leftChild = left; 45 | rightChild = right; 46 | } 47 | 48 | /** 49 | * Express a BinaryTreeNode as a String. 50 | * 51 | * @return a String representing the BinaryTreeNode. 52 | **/ 53 | public String toString() { 54 | String s = ""; 55 | 56 | if (leftChild != null) { 57 | s = "(" + leftChild.toString() + ")"; 58 | } 59 | s = s + entry.key().toString() + entry.value(); 60 | if (rightChild != null) { 61 | s = s + "(" + rightChild.toString() + ")"; 62 | } 63 | return s; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lab/lab11/dict/Dictionary.java: -------------------------------------------------------------------------------- 1 | /* Dictionary.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * An interface for (unordered) dictionary ADTs. 7 | * 8 | * DO NOT CHANGE THIS FILE. 9 | **/ 10 | 11 | public interface Dictionary { 12 | 13 | /** 14 | * Returns the number of entries stored in the dictionary. Entries with 15 | * the same key (or even the same key and value) each still count as 16 | * a separate entry. 17 | * @return number of entries in the dictionary. 18 | **/ 19 | 20 | public int size(); 21 | 22 | /** 23 | * Tests if the dictionary is empty. 24 | * 25 | * @return true if the dictionary has no entries; false otherwise. 26 | **/ 27 | 28 | public boolean isEmpty(); 29 | 30 | /** 31 | * Create a new Entry object referencing the input key and associated value, 32 | * and insert the entry into the dictionary. Return a reference to the new 33 | * entry. Multiple entries with the same key (or even the same key and 34 | * value) can coexist in the dictionary. 35 | * 36 | * @param key the key by which the entry can be retrieved. 37 | * @param value an arbitrary object. 38 | * @return an entry containing the key and value. 39 | **/ 40 | 41 | public Entry insert(Object key, Object value); 42 | 43 | /** 44 | * Search for an entry with the specified key. If such an entry is found, 45 | * return it; otherwise return null. If several entries have the specified 46 | * key, choose one arbitrarily and return it. 47 | * 48 | * @param key the search key. 49 | * @return an entry containing the key and an associated value, or null if 50 | * no entry contains the specified key. 51 | **/ 52 | 53 | public Entry find(Object key); 54 | 55 | /** 56 | * Remove an entry with the specified key. If such an entry is found, 57 | * remove it from the table and return it; otherwise return null. 58 | * If several entries have the specified key, choose one arbitrarily, then 59 | * remove and return it. 60 | * 61 | * @param key the search key. 62 | * @return an entry containing the key and an associated value, or null if 63 | * no entry contains the specified key. 64 | */ 65 | 66 | public Entry remove(Object key); 67 | 68 | /** 69 | * Remove all entries from the dictionary. 70 | */ 71 | 72 | public void makeEmpty(); 73 | 74 | } 75 | -------------------------------------------------------------------------------- /lab/lab11/dict/Entry.java: -------------------------------------------------------------------------------- 1 | /* Entry.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * A class for dictionary entries, which are (key, value) pairs. 7 | * 8 | * DO NOT CHANGE THIS FILE. It is part of the interface of the Dictionary 9 | * ADT. 10 | **/ 11 | 12 | public class Entry { 13 | 14 | protected Object key; 15 | protected Object value; 16 | 17 | protected Entry() { 18 | } 19 | 20 | protected Entry(Object k, Object v) { 21 | key = k; 22 | value = v; 23 | } 24 | 25 | public Object key() { 26 | return key; 27 | } 28 | 29 | public Object value() { 30 | return value; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lab/lab12/SortPerf.java: -------------------------------------------------------------------------------- 1 | /* SortPerf.java */ 2 | 3 | import java.util.Random; 4 | import java.io.*; 5 | 6 | class SortPerf { 7 | 8 | private static final long INIT_SEED = 1234567; 9 | 10 | /** 11 | * Times a sorting algorithm on data for arrays of size incN, 2 * incN, ..., 12 | * maxN and writes the timing data to "outFileName". 13 | * 14 | * For an array of each size, sorts the random data numTrials times to 15 | * produce an total running time. 16 | **/ 17 | public static void main(String[] argv) throws IOException { 18 | 19 | String outFileName = ""; 20 | int incN = 0; 21 | int maxN = 0; 22 | int numTrials = 0; 23 | String sortAlg = ""; 24 | if (argv.length != 5) { 25 | printUsage(); 26 | return; 27 | } else try { 28 | sortAlg = argv[0]; 29 | incN = Integer.parseInt(argv[1]); 30 | maxN = Integer.parseInt(argv[2]); 31 | numTrials = Integer.parseInt(argv[3]); 32 | outFileName = argv[4]; 33 | } catch (Exception e) { 34 | printUsage(); 35 | return; 36 | } 37 | PrintWriter timings = new PrintWriter(new FileOutputStream(outFileName)); 38 | timings.println("# Results for " + numTrials + " trials"); 39 | timings.println("# n time (msec)"); 40 | timings.println("# ---------------"); 41 | 42 | timeSort(timings, incN, maxN, numTrials, sortAlg); 43 | timings.close(); 44 | System.out.println("done! results in `" + outFileName + "'"); 45 | } 46 | 47 | /** 48 | * Times a sorting algorithm on data for arrays of size incN, 2 * incN, ..., 49 | * maxN. Performs numTrials trials and computes the total running time. 50 | */ 51 | private static void timeSort(PrintWriter timings, int incN, int maxN, 52 | int numTrials, String sortAlg) { 53 | Timer stopWatch = new Timer(); 54 | for (int n = incN; n <= maxN; n += incN) { 55 | System.out.println("timing n == " + n + " ... "); 56 | stopWatch.reset(); 57 | int[][] data = new int[numTrials + 1][]; 58 | for (int t = 0; t < numTrials + 1; t++) { 59 | data[t] = randomData(n); 60 | } 61 | if (sortAlg.equals("insert")) { 62 | Sort.insertionSort(data[numTrials]); // sort once without counting 63 | stopWatch.start(); 64 | for (int t = 0; t < numTrials; t++) { 65 | Sort.insertionSort(data[t]); 66 | } 67 | stopWatch.stop(); 68 | } else if (sortAlg.equals("select")) { 69 | Sort.selectionSort(data[numTrials]); // sort once without counting 70 | stopWatch.start(); 71 | for(int t = 0; t < numTrials; t++) { 72 | Sort.selectionSort(data[t]); 73 | } 74 | stopWatch.stop(); 75 | } else if (sortAlg.equals("merge")) { 76 | Sort.mergeSort(data[numTrials]); // sort once without counting 77 | stopWatch.start(); 78 | for (int t = 0; t < numTrials; t++) { 79 | Sort.mergeSort(data[t]); 80 | } 81 | stopWatch.stop(); 82 | } else if (sortAlg.equals("quick")) { 83 | Sort.quicksort(data[numTrials]); // sort once without counting 84 | stopWatch.start(); 85 | for(int t = 0; t < numTrials; t++) { 86 | Sort.quicksort(data[t]); 87 | } 88 | stopWatch.stop(); 89 | } else if (sortAlg.equals("best")) { 90 | YourSort.sort(data[numTrials]); // sort once without counting 91 | stopWatch.start(); 92 | for(int t = 0; t < numTrials; t++) { 93 | YourSort.sort(data[t]); 94 | } 95 | stopWatch.stop(); 96 | } else { 97 | printUsage(); 98 | return; 99 | } 100 | long totalTime = stopWatch.elapsed(); 101 | timings.println(n + " " + totalTime); 102 | } 103 | } 104 | 105 | // Prints the contents of A. 106 | private static void printData(int[] A) { 107 | for (int i = 0; i < A.length - 1; i++) { 108 | System.out.print(A[i] + ", "); 109 | } 110 | if (A.length - 1 >= 0) { 111 | System.out.println(A[A.length - 1]); 112 | } 113 | } 114 | 115 | /** 116 | * Assumes n > 0 117 | * Returns an array of `n' randomly selected integers. 118 | **/ 119 | private static int[] randomData(int n) { 120 | 121 | // choose same sequence of random numbers so that 122 | // we can fairly compare our sorting algorithms 123 | 124 | Random randGen = new Random(INIT_SEED); 125 | 126 | int[] newData = new int[n]; 127 | for (int i = 0; i < n; i++) { 128 | newData[i] = randGen.nextInt(); 129 | } 130 | 131 | return newData; 132 | } 133 | 134 | /** Print a message saying how the main method should be called. */ 135 | private static void printUsage() { 136 | System.out.println("Usage:"); 137 | System.out.println(" java SortPerf "); 138 | System.out.println(" sort - one of insert, merge, quick, or best"); 139 | System.out.println(" incr - the initial array size and increment"); 140 | System.out.println(" max - the maximum array size"); 141 | System.out.println(" runs - the number of runs for each size"); 142 | System.out.println(" outfile - is the name of the timing output file"); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /lab/lab12/Timer.java: -------------------------------------------------------------------------------- 1 | /* Timer.java */ 2 | 3 | /** 4 | * Implements a simple stopwatch/timer class based on wall-clock time. 5 | **/ 6 | 7 | /** 8 | * RUNNING() == true <==> start() called with no corresponding 9 | * call to stop() 10 | * 11 | * All times are given in units of msec. 12 | **/ 13 | public class Timer { 14 | 15 | private boolean running; 16 | private long tStart; 17 | private long tFinish; 18 | private long tAccum; 19 | 20 | /** 21 | * Initializes Timer to 0 msec 22 | **/ 23 | public Timer() { 24 | reset(); 25 | } 26 | 27 | /** 28 | * Starts the timer. Accumulates time across multiple calls to start. 29 | **/ 30 | public void start() { 31 | running = true; 32 | tStart = System.currentTimeMillis(); 33 | tFinish = tStart; 34 | } 35 | 36 | /** 37 | * Stops the timer. returns the time elapsed since the last matching call 38 | * to start(), or zero if no such matching call was made. 39 | **/ 40 | public long stop() { 41 | tFinish = System.currentTimeMillis(); 42 | if (running) { 43 | running = false; 44 | 45 | long diff = tFinish - tStart; 46 | tAccum += diff; 47 | return diff; 48 | } 49 | return 0; 50 | } 51 | 52 | /** 53 | * if RUNNING() ==> returns the time since last call to start() 54 | * if !RUNNING() ==> returns total elapsed time 55 | **/ 56 | public long elapsed() { 57 | if (running) { 58 | return System.currentTimeMillis() - tStart; 59 | } 60 | 61 | return tAccum; 62 | } 63 | 64 | /** 65 | * Stops timing, if currently RUNNING(); resets 66 | * accumulated time to 0. 67 | */ 68 | public void reset() { 69 | running = false; 70 | tStart = 0; 71 | tFinish = 0; 72 | tAccum = 0; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /lab/lab12/YourSort.java: -------------------------------------------------------------------------------- 1 | /* YourSort.java */ 2 | 3 | public class YourSort { 4 | 5 | public static void sort(int[] A) { 6 | // Place your Part III code here. 7 | if(A.length < 50) { 8 | Sort.insertionSort(A); 9 | } else { 10 | Sort.quicksort(A); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lab/lab13/UDGraph.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/lab/lab13/UDGraph.class -------------------------------------------------------------------------------- /lab/lab14/dict/BinaryTreeNode.java: -------------------------------------------------------------------------------- 1 | /* BinaryTreeNode.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * BinaryTreeNode represents a node in a binary tree. 7 | * 8 | * DO NOT CHANGE THIS FILE. 9 | **/ 10 | class BinaryTreeNode { 11 | 12 | /** 13 | * entry is a (key, value) pair stored in this node. 14 | * parent is the parent of this node. 15 | * leftChild and rightChild are the children of this node. 16 | **/ 17 | Entry entry; 18 | BinaryTreeNode parent; 19 | BinaryTreeNode leftChild, rightChild; 20 | 21 | /** 22 | * Construct a BinaryTreeNode with a specified entry; parent and children 23 | * are null. 24 | **/ 25 | BinaryTreeNode(Entry entry) { 26 | this(entry, null, null, null); 27 | } 28 | 29 | /** 30 | * Construct a BinaryTreeNode with a specified entry and parent; children 31 | * are null. 32 | **/ 33 | BinaryTreeNode(Entry entry, BinaryTreeNode parent) { 34 | this(entry, parent, null, null); 35 | } 36 | 37 | /** 38 | * Construct a BinaryTreeNode, specifying all four fields. 39 | **/ 40 | BinaryTreeNode(Entry entry, BinaryTreeNode parent, 41 | BinaryTreeNode left, BinaryTreeNode right) { 42 | this.entry = entry; 43 | this.parent = parent; 44 | leftChild = left; 45 | rightChild = right; 46 | } 47 | 48 | /** 49 | * Express a BinaryTreeNode as a String. 50 | * 51 | * @return a String representing the BinaryTreeNode. 52 | **/ 53 | public String toString() { 54 | String s = ""; 55 | 56 | if (leftChild != null) { 57 | s = "(" + leftChild.toString() + ")"; 58 | } 59 | s = s + entry.key().toString() + entry.value(); 60 | if (rightChild != null) { 61 | s = s + "(" + rightChild.toString() + ")"; 62 | } 63 | return s; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lab/lab14/dict/Dictionary.java: -------------------------------------------------------------------------------- 1 | /* Dictionary.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * An interface for dictionary ADTs. 7 | * 8 | * DO NOT CHANGE THIS FILE. 9 | **/ 10 | 11 | public interface Dictionary { 12 | 13 | /** 14 | * size() returns the number of entries stored in the dictionary. Entries 15 | * with the same key (or even the same key and value) each still count as 16 | * a separate entry. 17 | * 18 | * @return the number of entries stored in the dictionary. 19 | **/ 20 | public int size(); 21 | 22 | /** 23 | * isEmpty() tests if the dictionary is empty. 24 | * 25 | * @return true if the dictionary has no entries; false otherwise. 26 | **/ 27 | public boolean isEmpty(); 28 | 29 | /** 30 | * insert() constructs and inserts a new Entry object, consisting of 31 | * a (key, value) pair, into the dictionary, and returns a reference to the 32 | * new Entry. Multiple entries with the same key (or even the same key and 33 | * value) can coexist in the dictionary. 34 | * 35 | * @param key the key by which the entry can be retrieved. 36 | * @param value an arbitrary object associated with the key. 37 | * @return an Entry object referencing the key and value. 38 | **/ 39 | public Entry insert(Object key, Object value); 40 | 41 | /** 42 | * find() searches for an entry with the specified key. If such an entry is 43 | * found, it returns the Entry object; otherwise, it returns null. If more 44 | * than one entry has the key, one of them is chosen arbitrarily and 45 | * returned. 46 | * 47 | * @param key the search key. 48 | * @return an Entry referencing the key and an associated value, or null if 49 | * no entry contains the specified key. 50 | **/ 51 | public Entry find(Object key); 52 | 53 | /** 54 | * remove() searches for an entry with the specified key. If such an entry 55 | * is found, it removes the Entry object from the Dictionary and returns it; 56 | * otherwise, it returns null. If more than one entry has the key, one of 57 | * them is chosen arbitrarily, removed, and returned. 58 | * 59 | * @param key the search key. 60 | * @return an Entry referencing the key and an associated value, or null if 61 | * no entry contains the specified key. 62 | **/ 63 | public Entry remove(Object key); 64 | 65 | /** 66 | * makeEmpty() removes all the entries from the dictionary. 67 | */ 68 | public void makeEmpty(); 69 | 70 | } 71 | -------------------------------------------------------------------------------- /lab/lab14/dict/Entry.java: -------------------------------------------------------------------------------- 1 | /* Entry.java */ 2 | 3 | package dict; 4 | 5 | /** 6 | * A class for dictionary entries, which are (key, value) pairs. 7 | * 8 | * DO NOT CHANGE THIS FILE. It is part of the interface of the Dictionary 9 | * ADT. 10 | **/ 11 | 12 | public class Entry { 13 | 14 | protected Object key; 15 | protected Object value; 16 | 17 | protected Entry() { 18 | } 19 | 20 | protected Entry(Object k, Object v) { 21 | key = k; 22 | value = v; 23 | } 24 | 25 | public Object key() { 26 | return key; 27 | } 28 | 29 | public Object value() { 30 | return value; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lab/lab15/GimmeYoNumber.java: -------------------------------------------------------------------------------- 1 | /* GimmeYoNumber.java */ 2 | 3 | import java.util.Random; 4 | import java.io.*; 5 | 6 | class GimmeYoNumber { 7 | 8 | public final static int LISTSIZE = 13; 9 | public final static int NUMCANDIDATES = 30; 10 | public final static int CANDIDATERANGE = 100; 11 | 12 | public static void main(String[] args) { 13 | Random rand = new Random(); 14 | int indexlist[] = new int[LISTSIZE]; 15 | int candidates[] = new int[NUMCANDIDATES]; 16 | int i, j, k; 17 | 18 | /* Create a list of LISTSIZE indexes, each indexing a randomly chosen */ 19 | /* candidate. (A candidate may be chosen multiple times.) */ 20 | for (i = 0; i < LISTSIZE; i++) { 21 | indexlist[i] = rand.nextInt(NUMCANDIDATES); 22 | } 23 | 24 | /* Create one list for each of the two opponents. */ 25 | for (k = 1; k <= 2; k++) { 26 | 27 | /* Generate NUMCANDIDATES candidate ints in the range */ 28 | /* 0...CANDIDATERANGE - 1. Candidates are (already) sorted. */ 29 | /* The number of candidates is smaller than the range because */ 30 | /* I want a high likelihood of duplicate keys. */ 31 | j = 0; 32 | for (i = 0; i < CANDIDATERANGE; i++) { 33 | if (rand.nextInt(CANDIDATERANGE - i) < NUMCANDIDATES - j) { 34 | candidates[j] = i; 35 | j++; 36 | } 37 | } 38 | 39 | /* Print the list of chosen candidates. */ 40 | System.out.println("Opponent " + k + ":"); 41 | for (i = 0; i < LISTSIZE; i++) { 42 | System.out.print(candidates[indexlist[i]] + " "); 43 | } 44 | System.out.println("\n"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lab/lab2/Fraction.java: -------------------------------------------------------------------------------- 1 | /* Fraction.java */ 2 | 3 | import java.io.*; 4 | 5 | /** The Fraction class implements nonnegative fractions (rational numbers). 6 | */ 7 | class Fraction { 8 | 9 | /* private fields within a Fraction. */ 10 | private static int numberOfFractions = 0; 11 | 12 | private int numerator; 13 | private int denominator; 14 | 15 | /** Constructs a Fraction n/d. 16 | * @param n is the numerator. Must be nonnegative. 17 | * @param d is the denominator. Must be positive. 18 | */ 19 | public Fraction(int n, int d) { 20 | if (n < 0) { 21 | System.out.println("Fatal error: Negative numerator."); 22 | System.exit(0); 23 | } 24 | if (d < 1) { 25 | System.out.println("Fatal error: Nonpositive denominator."); 26 | System.exit(0); 27 | } 28 | numberOfFractions++; 29 | numerator = n; 30 | denominator = d; 31 | } 32 | 33 | /** Constructs a Fraction n/1. 34 | * @param n is the numerator. Must be nonnegative. 35 | */ 36 | public Fraction(int n) { 37 | this(n, 1); 38 | } 39 | 40 | /** Constructs a Fraction 0/1. 41 | */ 42 | public Fraction() { 43 | this(0, 1); 44 | } 45 | 46 | /** Copies the Fraction "original". 47 | */ 48 | public Fraction(Fraction original) { 49 | numberOfFractions++; 50 | numerator = original.numerator; 51 | denominator = original.denominator; 52 | } 53 | 54 | /** Converts this Fraction to a string format: "numerator/denominator." 55 | * Fractions should be printed in reduced form (part of your assignment is 56 | * to make this true). 57 | * @return a String representation of this Fraction. 58 | */ 59 | public String toString() { 60 | int thisGcd = gcd(numerator, denominator); 61 | 62 | return (numerator / thisGcd + "/" + denominator / thisGcd); 63 | } 64 | 65 | /** Return the sum of two fractions. 66 | * @param f2 is the Fraction to be added. 67 | * @return the result of adding f2 to this Fraction. 68 | */ 69 | public Fraction add(Fraction f2) { 70 | Fraction r = new Fraction((numerator * f2.denominator) + 71 | (f2.numerator * denominator), 72 | denominator * f2.denominator); 73 | return r; 74 | } 75 | 76 | /** Replaces this Fraction's numerator with a new value. 77 | * @param numerator is the new numerator. Must be nonnegative. 78 | */ 79 | public void changeNumerator(int numerator) { // DO NOT CHANGE THIS SIGNATURE! 80 | // Fix the bug that prevents this method from working correctly. 81 | if (numerator < 0) { 82 | System.out.println("Fatal error: Negative numerator."); 83 | System.exit(0); 84 | } 85 | this.numerator = numerator; 86 | } 87 | 88 | /** Returns the number of Fraction objects in existence. 89 | * @return the number of Fraction objects in existence. 90 | */ 91 | public int fracs() { // DO NOT CHANGE THIS SIGNATURE! 92 | // Fix the bug that prevents this method from working correctly. 93 | return numberOfFractions; 94 | } 95 | 96 | /** Computes the greatest common divisor (gcd) of the two inputs. 97 | * @param x must be nonnegative 98 | * @param y must be nonnegative 99 | * @return the gcd of x and y 100 | */ 101 | static private int gcd(int x, int y) { 102 | /* Replace the following line with your solution. */ 103 | if(y == 0){ 104 | return x; 105 | }else{ 106 | return gcd(y, x % y); 107 | } 108 | } 109 | 110 | /** Put the Fraction class through some tests. 111 | * @param argv is not used. 112 | */ 113 | public static void main(String[] argv) { 114 | 115 | /* Test all four contructors and toString. */ 116 | Fraction f0 = new Fraction(); 117 | Fraction f1 = new Fraction(3); 118 | Fraction f2 = new Fraction(12, 20); 119 | Fraction f3 = new Fraction(f2); 120 | 121 | System.out.println("\nTesting constructors and toString():"); 122 | System.out.println("The fraction f0 is " + f0.toString()); 123 | System.out.println("The fraction f1 is " + f1); // toString is implicit. 124 | System.out.println("The fraction f2 is " + f2); 125 | System.out.println("The fraction f3 is " + f3 + ", which should equal f2"); 126 | 127 | /* Test the add method. */ 128 | System.out.println("\nTesting add:"); 129 | 130 | 131 | Fraction sumOfTwo = f1.add(f2); // Sum of f1 and f2. 132 | Fraction sumOfThree = f0.add(sumOfTwo); // Sum of f0, f1, and f2. 133 | 134 | System.out.println("The sum of " + f1 + " and " + f2 + " is " + sumOfTwo); 135 | System.out.println("The sum of " + f0 + ", " + f1 + " and " + f2 + " is " + 136 | sumOfThree); 137 | 138 | 139 | /* Test the methods used in Part III. */ 140 | System.out.println("\nTesting changeNumerator and fracs:"); 141 | 142 | f3.changeNumerator(7); 143 | System.out.println("Now f3 is " + f3 + ", which should be 7/20"); 144 | System.out.println("The total number of Fraction objects is " + 145 | f3.fracs()); 146 | 147 | /* Test gcd function (static method). */ 148 | System.out.println("\nTesting gcd:"); 149 | System.out.println("The gcd of 2 and 10 is: " + gcd(2, 10)); 150 | System.out.println("The gcd of 15 and 5 is: " + gcd(15, 5)); 151 | System.out.println("The gcd of 24 and 18 is: " + gcd(24, 18)); 152 | System.out.println("The gcd of 10 and 10 is: " + gcd(10, 10)); 153 | System.out.println("The gcd of 21 and 400 is: " + gcd(21, 400)); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /lab/lab3/SList.java: -------------------------------------------------------------------------------- 1 | /* SList.java */ 2 | 3 | /** 4 | * The SList class is a singly-linked implementation of the linked list 5 | * abstraction. SLists are mutable data structures, which can grow at either 6 | * end. 7 | * 8 | * @author Kathy Yelick and Jonathan Shewchuk 9 | **/ 10 | 11 | public class SList { 12 | 13 | private SListNode head; 14 | private SListNode tail; 15 | private int size; 16 | 17 | /** 18 | * SList() constructs an empty list. 19 | **/ 20 | 21 | public SList() { 22 | size = 0; 23 | head = null; 24 | } 25 | 26 | /** 27 | * isEmpty() indicates whether the list is empty. 28 | * @return true if the list is empty, false otherwise. 29 | **/ 30 | 31 | public boolean isEmpty() { 32 | return size == 0; 33 | } 34 | 35 | /** 36 | * length() returns the length of this list. 37 | * @return the length of this list. 38 | **/ 39 | 40 | public int length() { 41 | return size; 42 | } 43 | 44 | /** 45 | * insertFront() inserts item "obj" at the beginning of this list. 46 | * @param obj the item to be inserted. 47 | **/ 48 | 49 | public void insertFront(Object obj) { 50 | head = new SListNode(obj, head); 51 | size++; 52 | if(tail == null) tail = head; 53 | } 54 | 55 | /** 56 | * insertEnd() inserts item "obj" at the end of this list. 57 | * @param obj the item to be inserted. 58 | **/ 59 | 60 | public void insertEnd(Object obj) { 61 | if (head == null) { 62 | head = new SListNode(obj); 63 | tail = head; 64 | } else { 65 | tail.next = new SListNode(obj); 66 | tail = tail.next; 67 | } 68 | size++; 69 | } 70 | 71 | /** 72 | * nth() returns the item at the specified position. If position < 1 or 73 | * position > this.length(), null is returned. Otherwise, the item at 74 | * position "position" is returned. The list does not change. 75 | * @param position the desired position, from 1 to length(), in the list. 76 | * @return the item at the given position in the list. 77 | **/ 78 | 79 | public Object nth(int position) { 80 | SListNode currentNode; 81 | 82 | if ((position < 1) || (head == null)) { 83 | return null; 84 | } else { 85 | currentNode = head; 86 | while (position > 1) { 87 | currentNode = currentNode.next; 88 | if (currentNode == null) { 89 | return null; 90 | } 91 | position--; 92 | } 93 | return currentNode.item; 94 | } 95 | } 96 | 97 | /** 98 | * toString() converts the list to a String. 99 | * @return a String representation of the list. 100 | **/ 101 | 102 | public String toString() { 103 | int i; 104 | Object obj; 105 | String result = "[ "; 106 | 107 | SListNode cur = head; 108 | 109 | while (cur != null) { 110 | obj = cur.item; 111 | result = result + obj.toString() + " "; 112 | cur = cur.next; 113 | } 114 | result = result + "]"; 115 | return result; 116 | } 117 | 118 | 119 | /** 120 | * main() runs test cases on the SList class. Prints summary 121 | * information on basic operations and halts with an error (and a stack 122 | * trace) if any of the tests fail. 123 | **/ 124 | 125 | public static void main (String[] args) { 126 | // Fill in your solution for Part I here. 127 | 128 | // testEmpty(); 129 | // testAfterInsertFront(); 130 | // testAfterInsertEnd(); 131 | SList l1 = new SList(); 132 | l1.insertEnd(new Integer(6)); 133 | l1.insertEnd(new Integer(9)); 134 | l1.insertEnd(new Integer(12)); 135 | l1.insertFront(new Integer(3)); 136 | l1.insertEnd(new Integer(15)); 137 | System.out.println("Here " 138 | + l1.toString()); 139 | } 140 | 141 | 142 | /** 143 | * testEmpty() tests toString(), isEmpty(), length(), insertFront(), and 144 | * insertEnd() on an empty list. Prints summary information of the tests 145 | * and halts the program if errors are detected. 146 | **/ 147 | 148 | private static void testEmpty() { 149 | SList lst1 = new SList(); 150 | SList lst2 = new SList(); 151 | System.out.println(); 152 | System.out.println("Here is a list after construction: " 153 | + lst1.toString()); 154 | TestHelper.verify(lst1.toString().equals("[ ]"), 155 | "toString on newly constructed list failed"); 156 | 157 | System.out.println("isEmpty() should be true. It is: " + 158 | lst1.isEmpty()); 159 | TestHelper.verify(lst1.isEmpty() == true, 160 | "isEmpty() on newly constructed list failed"); 161 | 162 | System.out.println("length() should be 0. It is: " + 163 | lst1.length()); 164 | TestHelper.verify(lst1.length() == 0, 165 | "length on newly constructed list failed"); 166 | lst1.insertFront(new Integer(3)); 167 | System.out.println("Here is a list after insertFront(3) to an empty list: " 168 | + lst1.toString()); 169 | TestHelper.verify(lst1.toString().equals("[ 3 ]"), 170 | "InsertFront on empty list failed"); 171 | lst2.insertEnd(new Integer(5)); 172 | System.out.println("Here is a list after insertEnd(5) on an empty list: " 173 | + lst2.toString()); 174 | TestHelper.verify(lst2.toString().equals("[ 5 ]"), 175 | "insertEnd on empty list failed"); 176 | } 177 | 178 | /** 179 | * testAfterInsertFront() tests toString(), isEmpty(), length(), 180 | * insertFront(), and insertEnd() after insertFront(). Prints summary 181 | * information of the tests and halts the program if errors are detected. 182 | **/ 183 | 184 | private static void testAfterInsertFront() { 185 | SList lst1 = new SList(); 186 | lst1.insertFront(new Integer(3)); 187 | lst1.insertFront(new Integer(2)); 188 | lst1.insertFront(new Integer(1)); 189 | System.out.println(); 190 | System.out.println("Here is a list after insertFront 3, 2, 1: " 191 | + lst1.toString()); 192 | TestHelper.verify(lst1.toString().equals("[ 1 2 3 ]"), 193 | "InsertFronts on non-empty list failed"); 194 | System.out.println("isEmpty() should be false. It is: " + 195 | lst1.isEmpty()); 196 | TestHelper.verify(lst1.isEmpty() == false, 197 | "isEmpty() after insertFront failed"); 198 | System.out.println("length() should be 3. It is: " + 199 | lst1.length()); 200 | TestHelper.verify(lst1.length() == 3, 201 | "length() after insertFront failed"); 202 | lst1.insertEnd(new Integer(4)); 203 | System.out.println("Here is the same list after insertEnd(4): " 204 | + lst1.toString()); 205 | TestHelper.verify(lst1.toString().equals("[ 1 2 3 4 ]"), 206 | "insertEnd on non-empty list failed"); 207 | } 208 | 209 | /** 210 | * testAfterInsertEnd() tests toString(), isEmpty(), length(), 211 | * insertFront(), and insertEnd() after insertEnd(). Prints summary 212 | * information of the tests and halts the program if errors are detected. 213 | **/ 214 | 215 | private static void testAfterInsertEnd() { 216 | SList lst1 = new SList(); 217 | lst1.insertEnd(new Integer(6)); 218 | lst1.insertEnd(new Integer(7)); 219 | System.out.println(); 220 | System.out.println("Here is a list after insertEnd 6, 7: " 221 | + lst1.toString()); 222 | System.out.println("isEmpty() should be false. It is: " + 223 | lst1.isEmpty()); 224 | TestHelper.verify(lst1.isEmpty() == false, 225 | "isEmpty() after insertEnd failed"); 226 | System.out.println("length() should be 2. It is: " + 227 | lst1.length()); 228 | TestHelper.verify(lst1.length() == 2, 229 | "length() after insertEndfailed"); 230 | lst1.insertFront(new Integer(5)); 231 | System.out.println("Here is the same list after insertFront(5): " 232 | + lst1.toString()); 233 | TestHelper.verify(lst1.toString().equals("[ 5 6 7 ]"), 234 | "insertFront after insertEnd failed"); 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /lab/lab3/SListNode.java: -------------------------------------------------------------------------------- 1 | /* SListNode.java */ 2 | 3 | /** 4 | * SListNode is a class used internally by the SList class. An SList object 5 | * is a singly-linked list, and an SListNode is a node of a singly-linked 6 | * list. Each SListNode has two references: one to an object, and one to 7 | * the next node in the list. 8 | * 9 | * @author Kathy Yelick and Jonathan Shewchuk 10 | */ 11 | 12 | class SListNode { 13 | Object item; 14 | SListNode next; 15 | 16 | /** 17 | * SListNode() (with one parameter) constructs a list node referencing the 18 | * item "obj". 19 | */ 20 | 21 | SListNode(Object obj) { 22 | item = obj; 23 | next = null; 24 | } 25 | 26 | /** 27 | * SListNode() (with two parameters) constructs a list node referencing the 28 | * item "obj", whose next list node is to be "next". 29 | */ 30 | 31 | SListNode(Object obj, SListNode next) { 32 | item = obj; 33 | this.next = next; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /lab/lab3/TestHelper.java: -------------------------------------------------------------------------------- 1 | /* TestHelper.java */ 2 | 3 | /** 4 | * This class is based on code from Arnow/Dexter/Weiss. Its verify() method 5 | * exits with an error message if an invariant fails to hold true. 6 | * 7 | * The purpose of this class is to provide a shorthand for writing and testing 8 | * invariants in any program. 9 | **/ 10 | 11 | public class TestHelper { 12 | 13 | /** 14 | * verify() checks an invariant and prints an error message if it fails. 15 | * If invariant is true, this method does nothing. If invariant is false, 16 | * the message is printed, followed by a dump of the program call stack. 17 | * 18 | * @param invariant the condition to be verified 19 | * @param message the error message to be printed if the invariant fails to 20 | * hold true. 21 | **/ 22 | 23 | static void verify(boolean invariant, String message) { 24 | if (!invariant) { 25 | System.out.println("*** ERROR: " + message); 26 | Thread.dumpStack(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lab/lab4/DList1.java: -------------------------------------------------------------------------------- 1 | /* DList1.java */ 2 | 3 | /** 4 | * A DList1 is a mutable doubly-linked list. (No sentinel, not 5 | * circularly linked.) 6 | */ 7 | 8 | public class DList1 { 9 | 10 | /** 11 | * head references the first node. 12 | * tail references the last node. 13 | * 14 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 15 | */ 16 | 17 | protected DListNode1 head; 18 | protected DListNode1 tail; 19 | protected long size; 20 | 21 | /* DList1 invariants: 22 | * 1) head.prev == null. 23 | * 2) tail.next == null. 24 | * 3) For any DListNode1 x in a DList, if x.next == y and x.next != null, 25 | * then y.prev == x. 26 | * 4) For any DListNode1 x in a DList, if x.prev == y and x.prev != null, 27 | * then y.next == x. 28 | * 5) The tail can be accessed from the head by a sequence of "next" 29 | * references. 30 | * 6) size is the number of DListNode1s that can be accessed from the 31 | * head by a sequence of "next" references. 32 | */ 33 | 34 | /** 35 | * DList1() constructor for an empty DList1. 36 | */ 37 | public DList1() { 38 | head = null; 39 | tail = null; 40 | size = 0; 41 | } 42 | 43 | /** 44 | * DList1() constructor for a one-node DList1. 45 | */ 46 | public DList1(int a) { 47 | head = new DListNode1(); 48 | tail = head; 49 | head.item = a; 50 | size = 1; 51 | } 52 | 53 | /** 54 | * DList1() constructor for a two-node DList1. 55 | */ 56 | public DList1(int a, int b) { 57 | head = new DListNode1(); 58 | head.item = a; 59 | tail = new DListNode1(); 60 | tail.item = b; 61 | head.next = tail; 62 | tail.prev = head; 63 | size = 2; 64 | } 65 | 66 | /** 67 | * insertFront() inserts an item at the front of a DList1. 68 | */ 69 | public void insertFront(int i) { 70 | // Your solution here. 71 | if(size == 0){ 72 | head = new DListNode1(i); 73 | tail = head; 74 | size++; 75 | }else{ 76 | DListNode1 newNode = new DListNode1(i); 77 | newNode.next = head; 78 | head.prev = newNode; 79 | head = newNode; 80 | size++; 81 | } 82 | } 83 | 84 | /** 85 | * removeFront() removes the first item (and node) from a DList1. If the 86 | * list is empty, do nothing. 87 | */ 88 | public void removeFront() { 89 | // Your solution here. 90 | if(size > 1){ 91 | head.next.prev = null; 92 | head = head.next; 93 | size--; 94 | }else if(size == 1){ 95 | head = null; 96 | tail = null; 97 | size--; 98 | } 99 | } 100 | 101 | /** 102 | * toString() returns a String representation of this DList. 103 | * 104 | * DO NOT CHANGE THIS METHOD. 105 | * 106 | * @return a String representation of this DList. 107 | */ 108 | public String toString() { 109 | String result = "[ "; 110 | DListNode1 current = head; 111 | while (current != null) { 112 | result = result + current.item + " "; 113 | current = current.next; 114 | } 115 | return result + "]"; 116 | } 117 | 118 | public static void main(String[] args) { 119 | // DO NOT CHANGE THE FOLLOWING CODE. 120 | 121 | DList1 l = new DList1(); 122 | System.out.println("### TESTING insertFront ###\nEmpty list is " + l); 123 | 124 | l.insertFront(9); 125 | System.out.println("\nInserting 9 at front.\nList with 9 is " + l); 126 | if (l.head == null) { 127 | System.out.println("head is null."); 128 | } else { 129 | if (l.head.item != 9) { 130 | System.out.println("head.item is wrong."); 131 | } 132 | if (l.head.prev != null) { 133 | System.out.println("head.prev is wrong."); 134 | } 135 | } 136 | if (l.tail == null) { 137 | System.out.println("tail is null."); 138 | } else { 139 | if (l.tail.item != 9) { 140 | System.out.println("tail.item is wrong."); 141 | } 142 | if (l.tail.next != null) { 143 | System.out.println("tail.next is wrong."); 144 | } 145 | } 146 | if (l.size != 1) { 147 | System.out.println("size is wrong."); 148 | } 149 | 150 | l.insertFront(8); 151 | System.out.println("\nInserting 8 at front.\nList with 8 and 9 is " + l); 152 | if (l.head == null) { 153 | System.out.println("head is null."); 154 | } else { 155 | if (l.head.item != 8) { 156 | System.out.println("head.item is wrong."); 157 | } 158 | if (l.head.prev != null) { 159 | System.out.println("head.prev is wrong."); 160 | } 161 | if (l.head.next != l.tail) { 162 | System.out.println("head.next is wrong."); 163 | } 164 | } 165 | if (l.tail == null) { 166 | System.out.println("tail is null."); 167 | } else { 168 | if (l.tail.item != 9) { 169 | System.out.println("tail.item is wrong."); 170 | } 171 | if (l.tail.next != null) { 172 | System.out.println("tail.next is wrong."); 173 | } 174 | if (l.tail.prev != l.head) { 175 | System.out.println("tail.prev is wrong."); 176 | } 177 | } 178 | if (l.size != 2) { 179 | System.out.println("size is wrong."); 180 | } 181 | 182 | 183 | 184 | l = new DList1(1, 2); 185 | System.out.println("\n\n### TESTING removeFront ###\nList with 1 and 2 is " 186 | + l); 187 | 188 | l.removeFront(); 189 | System.out.println("\nRemoving front node.\nList with 2 is " + l); 190 | if (l.head.item != 2) { 191 | System.out.println("head.item is wrong."); 192 | } 193 | if (l.head.prev != null) { 194 | System.out.println("head.prev is wrong."); 195 | } 196 | if (l.tail.item != 2) { 197 | System.out.println("tail.item is wrong."); 198 | } 199 | if (l.tail.next != null) { 200 | System.out.println("tail.next is wrong."); 201 | } 202 | if (l.size != 1) { 203 | System.out.println("size is wrong."); 204 | } 205 | 206 | l.removeFront(); 207 | System.out.println("\nRemoving front node.\nEmpty list is " + l); 208 | if (l.head != null) { 209 | System.out.println("head is wrong."); 210 | } 211 | if (l.tail != null) { 212 | System.out.println("tail is wrong."); 213 | } 214 | if (l.size != 0) { 215 | System.out.println("size is wrong."); 216 | } 217 | 218 | l.removeFront(); 219 | System.out.println("\nRemoving front node.\nEmpty list is " + l); 220 | if (l.head != null) { 221 | System.out.println("head is wrong."); 222 | } 223 | if (l.tail != null) { 224 | System.out.println("tail is wrong."); 225 | } 226 | if (l.size != 0) { 227 | System.out.println("size is wrong."); 228 | } 229 | } 230 | 231 | } 232 | -------------------------------------------------------------------------------- /lab/lab4/DList2.java: -------------------------------------------------------------------------------- 1 | /* DList2.java */ 2 | 3 | /** 4 | * A DList2 is a mutable doubly-linked list. Its implementation is 5 | * circularly-linked and employs a sentinel (dummy) node at the head 6 | * of the list. 7 | */ 8 | 9 | public class DList2 { 10 | 11 | /** 12 | * head references the sentinel node. 13 | * 14 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 15 | */ 16 | 17 | protected DListNode2 head; 18 | protected long size; 19 | 20 | /* DList2 invariants: 21 | * 1) head != null. 22 | * 2) For any DListNode2 x in a DList2, x.next != null. 23 | * 3) For any DListNode2 x in a DList2, x.prev != null. 24 | * 4) For any DListNode2 x in a DList2, if x.next == y, then y.prev == x. 25 | * 5) For any DListNode2 x in a DList2, if x.prev == y, then y.next == x. 26 | * 6) size is the number of DListNode2s, NOT COUNTING the sentinel 27 | * (denoted by "head"), that can be accessed from the sentinel by 28 | * a sequence of "next" references. 29 | */ 30 | 31 | /** 32 | * DList2() constructor for an empty DList2. 33 | */ 34 | public DList2() { 35 | head = new DListNode2(); 36 | head.item = Integer.MIN_VALUE; 37 | head.next = head; 38 | head.prev = head; 39 | size = 0; 40 | } 41 | 42 | /** 43 | * DList2() constructor for a one-node DList2. 44 | */ 45 | public DList2(int a) { 46 | head = new DListNode2(); 47 | head.item = Integer.MIN_VALUE; 48 | head.next = new DListNode2(); 49 | head.next.item = a; 50 | head.prev = head.next; 51 | head.next.prev = head; 52 | head.prev.next = head; 53 | size = 1; 54 | } 55 | 56 | /** 57 | * DList2() constructor for a two-node DList2. 58 | */ 59 | public DList2(int a, int b) { 60 | head = new DListNode2(); 61 | head.item = Integer.MIN_VALUE; 62 | head.next = new DListNode2(); 63 | head.next.item = a; 64 | head.prev = new DListNode2(); 65 | head.prev.item = b; 66 | head.next.prev = head; 67 | head.next.next = head.prev; 68 | head.prev.next = head; 69 | head.prev.prev = head.next; 70 | size = 2; 71 | } 72 | 73 | /** 74 | * insertFront() inserts an item at the front of a DList2. 75 | */ 76 | public void insertFront(int i) { 77 | // Your solution here. 78 | DListNode2 newNode =new DListNode2(i); 79 | newNode.next = head.next; 80 | head.next.prev = newNode; 81 | newNode.prev = head; 82 | head.next = newNode; 83 | size++; 84 | } 85 | 86 | /** 87 | * removeFront() removes the first item (and first non-sentinel node) from 88 | * a DList2. If the list is empty, do nothing. 89 | */ 90 | public void removeFront() { 91 | // Your solution here. 92 | if(size > 0){ 93 | head.next = head.next.next; 94 | head.next.prev = head; 95 | size--; 96 | } 97 | } 98 | 99 | /** 100 | * toString() returns a String representation of this DList. 101 | * 102 | * DO NOT CHANGE THIS METHOD. 103 | * 104 | * @return a String representation of this DList. 105 | */ 106 | public String toString() { 107 | String result = "[ "; 108 | DListNode2 current = head.next; 109 | while (current != head) { 110 | result = result + current.item + " "; 111 | current = current.next; 112 | } 113 | return result + "]"; 114 | } 115 | 116 | public static void main(String[] args) { 117 | // DO NOT CHANGE THE FOLLOWING CODE. 118 | 119 | DList2 l = new DList2(); 120 | System.out.println("### TESTING insertFront ###\nEmpty list is " + l); 121 | 122 | l.insertFront(9); 123 | System.out.println("\nInserting 9 at front.\nList with 9 is " + l); 124 | if (l.head.next.item != 9) { 125 | System.out.println("head.next.item is wrong."); 126 | } 127 | if (l.head.next.prev != l.head) { 128 | System.out.println("head.next.prev is wrong."); 129 | } 130 | if (l.head.prev.item != 9) { 131 | System.out.println("head.prev.item is wrong."); 132 | } 133 | if (l.head.prev.next != l.head) { 134 | System.out.println("head.prev.next is wrong."); 135 | } 136 | if (l.size != 1) { 137 | System.out.println("size is wrong."); 138 | } 139 | 140 | l.insertFront(8); 141 | System.out.println("\nInserting 8 at front.\nList with 8 and 9 is " + l); 142 | if (l.head.next.item != 8) { 143 | System.out.println("head.next.item is wrong."); 144 | } 145 | if (l.head.next.prev != l.head) { 146 | System.out.println("head.next.prev is wrong."); 147 | } 148 | if (l.head.prev.item != 9) { 149 | System.out.println("head.prev.item is wrong."); 150 | } 151 | if (l.head.prev.next != l.head) { 152 | System.out.println("head.prev.next is wrong."); 153 | } 154 | if (l.head.next.next != l.head.prev) { 155 | System.out.println("l.head.next.next != l.head.prev."); 156 | } 157 | if (l.head.prev.prev != l.head.next) { 158 | System.out.println("l.head.prev.prev != l.head.next."); 159 | } 160 | if (l.size != 2) { 161 | System.out.println("size is wrong."); 162 | } 163 | 164 | 165 | 166 | l = new DList2(1, 2); 167 | System.out.println("\n\n### TESTING removeFront ###\nList with 1 and 2 is " 168 | + l); 169 | 170 | l.removeFront(); 171 | System.out.println("\nList with 2 is " + l); 172 | if (l.head.next.item != 2) { 173 | System.out.println("head.next.item is wrong."); 174 | } 175 | if (l.head.next.prev != l.head) { 176 | System.out.println("head.next.prev is wrong."); 177 | } 178 | if (l.head.prev.item != 2) { 179 | System.out.println("head.prev.item is wrong."); 180 | } 181 | if (l.head.prev.next != l.head) { 182 | System.out.println("head.prev.next is wrong."); 183 | } 184 | if (l.size != 1) { 185 | System.out.println("size is wrong."); 186 | } 187 | 188 | l.removeFront(); 189 | System.out.println("\nEmpty list is " + l); 190 | if (l.head.next != l.head) { 191 | System.out.println("head.next is wrong."); 192 | } 193 | if (l.head.prev != l.head) { 194 | System.out.println("head.prev is wrong."); 195 | } 196 | if (l.size != 0) { 197 | System.out.println("size is wrong."); 198 | } 199 | 200 | l.removeFront(); 201 | System.out.println("\nEmpty list is " + l); 202 | if (l.head.next != l.head) { 203 | System.out.println("head.next is wrong."); 204 | } 205 | if (l.head.prev != l.head) { 206 | System.out.println("head.prev is wrong."); 207 | } 208 | if (l.size != 0) { 209 | System.out.println("size is wrong."); 210 | } 211 | } 212 | 213 | } 214 | -------------------------------------------------------------------------------- /lab/lab4/DListNode1.java: -------------------------------------------------------------------------------- 1 | /* DListNode1.java */ 2 | 3 | /** 4 | * A DListNode1 is a node in a DList1 (doubly-linked list). 5 | */ 6 | 7 | public class DListNode1 { 8 | 9 | /** 10 | * item references the item stored in the current node. 11 | * prev references the previous node in the DList. 12 | * next references the next node in the DList. 13 | * 14 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 15 | */ 16 | 17 | public int item; 18 | public DListNode1 prev; 19 | public DListNode1 next; 20 | 21 | /** 22 | * DListNode1() constructor. 23 | */ 24 | DListNode1() { 25 | item = 0; 26 | prev = null; 27 | next = null; 28 | } 29 | 30 | DListNode1(int i) { 31 | item = i; 32 | prev = null; 33 | next = null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lab/lab4/DListNode2.java: -------------------------------------------------------------------------------- 1 | /* DListNode2.java */ 2 | 3 | /** 4 | * A DListNode2 is a node in a DList2 (doubly-linked list). 5 | */ 6 | 7 | public class DListNode2 { 8 | 9 | /** 10 | * item references the item stored in the current node. 11 | * prev references the previous node in the DList. 12 | * next references the next node in the DList. 13 | * 14 | * DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS. 15 | */ 16 | 17 | public int item; 18 | public DListNode2 prev; 19 | public DListNode2 next; 20 | 21 | /** 22 | * DListNode2() constructor. 23 | */ 24 | DListNode2() { 25 | item = 0; 26 | prev = null; 27 | next = null; 28 | } 29 | 30 | DListNode2(int i) { 31 | item = i; 32 | prev = null; 33 | next = null; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /lab/lab6/AccountData.java: -------------------------------------------------------------------------------- 1 | /* AccountData.java */ 2 | 3 | import sortedlist.*; 4 | 5 | /** 6 | * Implements a customer's account profile for the virtual teller machine. 7 | **/ 8 | public class AccountData implements Keyable { 9 | private String name; // Customer name. 10 | private int balance; // Starting balance. 11 | private int number; // Account number. 12 | 13 | /** 14 | * Constructs a new account for customer "newName" with acount number "num" 15 | * and a $0 starting balance. 16 | **/ 17 | public AccountData(String newName, int num) { 18 | name = newName; 19 | number = num; 20 | balance = 0; 21 | } 22 | 23 | /** 24 | * lessThan() returns true if this account's number is less than the 25 | * argument's account number. 26 | **/ 27 | public boolean lessThan(Keyable x) { 28 | return number < ((AccountData) x).number; 29 | } 30 | 31 | /** 32 | * getOwner() returns the name of this account's owner. 33 | **/ 34 | public String getOwner() { 35 | return name; 36 | } 37 | 38 | /** 39 | * toString() returns a String version of this account's number. 40 | **/ 41 | public String toString() { 42 | return "" + number; 43 | } 44 | 45 | 46 | /** 47 | * getBalance() returns the balance of this account. 48 | **/ 49 | public int getBalance() { 50 | return balance; 51 | } 52 | 53 | /** 54 | * withdraw() reduces the balance by the withdrawal amount "amt". 55 | **/ 56 | public void withdraw(int amt) { 57 | if (amt <= balance) { 58 | balance = balance - amt; 59 | } else { 60 | System.out.println("Error: Insufficient funds: " + amt); 61 | } 62 | } 63 | 64 | /** 65 | * deposit() deposits "amt" dollars into this account. 66 | **/ 67 | public void deposit(int amt) { 68 | if (amt >= 0) { 69 | balance = balance + amt; 70 | } else { 71 | System.out.println("Error: Tried to deposit less than 0: " + amt); 72 | } 73 | } 74 | 75 | /** 76 | * getNumber() returns this account's number. 77 | **/ 78 | public int getNumber() { 79 | return number; 80 | } 81 | 82 | /** 83 | * getKey() returns this account's account number as the key to use for 84 | * sorting and comparison. 85 | **/ 86 | public int getKey() { 87 | return number; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lab/lab6/BadAccountException.java: -------------------------------------------------------------------------------- 1 | /* BadAccountException.java */ 2 | 3 | /** 4 | * Implements an exception that should be thrown for nonexistent accounts. 5 | **/ 6 | public class BadAccountException extends Exception { 7 | 8 | public int accountNumber; // The invalid account number. 9 | 10 | /** 11 | * Creates an exception object for nonexistent account "badAcctNumber". 12 | **/ 13 | public BadAccountException(int badAcctNumber) { 14 | super("Invalid account number: " + badAcctNumber); 15 | 16 | accountNumber = badAcctNumber; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lab/lab6/BadTransactionException.java: -------------------------------------------------------------------------------- 1 | /* BadTransactionException.java */ 2 | 3 | public class BadTransactionException extends Exception { 4 | 5 | public int amountNumber; // The invalid account number. 6 | 7 | public BadTransactionException(int badAmount) { 8 | super("Invalid amount: " + badAmount); 9 | 10 | amountNumber = badAmount; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lab/lab6/BankApp.java: -------------------------------------------------------------------------------- 1 | /* BankApp.java */ 2 | 3 | import java.io.*; 4 | import sortedlist.*; 5 | 6 | /** 7 | * A bank application. Allows a user to create and manipulate 8 | * banking accounts, using an ATM that is shared by all banking applications. 9 | */ 10 | public class BankApp { 11 | private BufferedReader bReader = 12 | new BufferedReader(new InputStreamReader(System.in)); 13 | private VirtualTeller ATM = new VirtualTeller(); 14 | 15 | public static void main(String[] args) { 16 | greeting(); 17 | usage(); 18 | BankApp bankApp = new BankApp(); 19 | try{ 20 | String command = bankApp.readLine("--> "); 21 | while (!command.equals("quit")) { 22 | try { 23 | if (command.equals("open")) { 24 | bankApp.open(); 25 | } else if (command.equals("deposit")) { 26 | bankApp.doDeposit(); 27 | } else if (command.equals("withdraw")) { 28 | bankApp.doWithdraw(); 29 | } else if (command.equals("inquire")) { 30 | bankApp.doInquire(); 31 | } else { 32 | System.err.println("Invalid command: " + command); 33 | usage(); 34 | } 35 | command = bankApp.readLine("--> "); 36 | } catch(BadAccountException e1){ 37 | System.err.println(e1); 38 | 39 | }catch(BadTransactionException e2){ 40 | System.err.println(e2); 41 | 42 | } catch(IOException e) { 43 | System.err.println(e); 44 | } 45 | // command = bankApp.readLine("--> "); 46 | 47 | } 48 | }catch(IOException e){ 49 | System.err.println(e); 50 | } 51 | } 52 | 53 | public BankApp() { 54 | // The field declarations have initializers; 55 | // no initialization is needed here. 56 | } 57 | 58 | /** 59 | * open() prompts the user to create an account and creates one in the ATM. 60 | * @exception IOException if there are problems reading user input. 61 | */ 62 | private void open() throws IOException { 63 | String name = readLine("Enter name: "); 64 | int newNum = ATM.openAccount(name); 65 | 66 | System.out.println(name + ", your new account number is: " + newNum); 67 | System.out.println("Thanks for opening an account with us!"); 68 | } 69 | 70 | /** 71 | * doDeposit() prompts the user for an account number and tries to perform a 72 | * deposit transaction on that account. 73 | * @exception IOException if there are problems reading user input. 74 | */ 75 | private void doDeposit() throws IOException, BadAccountException { 76 | // Get account number. 77 | int acctNumber = readInt("Enter account number: "); 78 | int amount = readInt("Enter amount to deposit: "); 79 | 80 | ATM.deposit(acctNumber, amount); 81 | System.out.println("New balance for #" + acctNumber + " is " + 82 | ATM.balanceInquiry(acctNumber)); 83 | } 84 | 85 | /** 86 | * doWithdraw() prompts the user for an account number and tries 87 | * to perform a withdrawal transaction from that account. 88 | * @exception IOException if there are problems reading user input. 89 | */ 90 | private void doWithdraw() throws IOException, BadAccountException, BadTransactionException { 91 | // Get account number. 92 | int acctNumber = readInt("Enter account number: "); 93 | int amount = readInt("Enter amount to withdraw: "); 94 | 95 | ATM.withdraw(acctNumber, amount); 96 | System.out.println("New balance for #" + acctNumber + " is " + 97 | ATM.balanceInquiry(acctNumber)); 98 | } 99 | 100 | /** 101 | * doInquire() prompts the user for an account number, then attempts to 102 | * discover and print that account's balance. 103 | * @exception IOException if there are problems reading user input. 104 | */ 105 | private void doInquire() throws IOException, BadAccountException { 106 | int acctNumber = readInt("Enter account number: "); 107 | 108 | System.out.println("Balance for #" + acctNumber + " is " + 109 | ATM.balanceInquiry(acctNumber)); 110 | } 111 | 112 | /** 113 | * greeting() displays a greeting message on the screen. 114 | */ 115 | private static void greeting() { 116 | System.out.println("-------------------"); 117 | System.out.println("Welcome to the bank"); 118 | System.out.println("-------------------"); 119 | System.out.println(); 120 | } 121 | 122 | /** 123 | * usage() displays instructions on using the command line arguments. 124 | */ 125 | private static void usage() { 126 | System.out.println("Valid commands are: " + 127 | "open, deposit, withdraw, inquire, quit"); 128 | } 129 | 130 | /** 131 | * readLine() prints the given prompt and returns a string from the 132 | * input stream. 133 | * @param prompt is the string printed to prompt the user. 134 | */ 135 | private String readLine(String prompt) throws IOException { 136 | System.out.print(prompt); 137 | System.out.flush(); 138 | return bReader.readLine(); 139 | } 140 | 141 | /** 142 | * readInt() returns an integer from the input stream after prompting 143 | * the user. 144 | * @param prompt is the string printed to prompt the user. 145 | * @return an int read from the user. 146 | */ 147 | private int readInt(String prompt) throws IOException { 148 | String text = readLine(prompt); 149 | return Integer.valueOf(text).intValue(); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /lab/lab6/VirtualTeller.java: -------------------------------------------------------------------------------- 1 | /* VirtualTeller.java */ 2 | 3 | import sortedlist.*; 4 | 5 | /** 6 | * An implementation of a virtual automated teller machine. 7 | **/ 8 | public class VirtualTeller { 9 | private static int nextAccountID = 100; 10 | private SortedList accounts; 11 | 12 | /** 13 | * Constructs a new virtual teller. 14 | **/ 15 | public VirtualTeller() { 16 | accounts = new SortedList(); 17 | } 18 | 19 | /** 20 | * openAccount() creates a new account for the customer "name". 21 | * @param name the customer's name. 22 | * @return the new account's ID number. 23 | **/ 24 | public int openAccount(String name) { 25 | AccountData newData = new AccountData(name, nextAccountID); 26 | accounts.insert(newData); 27 | 28 | nextAccountID++; 29 | return newData.getNumber(); 30 | } 31 | 32 | /** 33 | * withdraw() withdraws "amount" dollars from the account whose number is 34 | * "acct". Assumes that amount >= 0. If "acct" is invalid, no action is 35 | * taken. 36 | * @param acct is an account number. 37 | * @param amount an amount of money. 38 | */ 39 | public void withdraw(int acct, int amount) throws BadAccountException, BadTransactionException{ 40 | AccountData account = findAccount(acct); 41 | 42 | if(amount < 0){ 43 | throw new BadTransactionException(amount); 44 | } 45 | 46 | // if (account == null) { // Didn't find the account. 47 | // System.out.println("Error: Couldn't find account number `" + 48 | // acct + "'" ); 49 | // } else { 50 | account.withdraw(amount); 51 | // } 52 | } 53 | 54 | /** 55 | * deposit() deposits "amount" dollars into the bank account whose number is 56 | * "acct". Assumes that amount >= 0. If "acct" is invalid, no action is 57 | * taken. 58 | * @param acct is an account number. 59 | * @param amount an amount of money. 60 | */ 61 | public void deposit(int acct, int amount) throws BadAccountException{ 62 | AccountData account = findAccount(acct); 63 | 64 | // if (account == null) { 65 | // System.out.println("Error: Couldn't find account number `" + 66 | // acct + "'"); 67 | // } else { 68 | account.deposit(amount); 69 | // } 70 | } 71 | 72 | /** 73 | * balanceInquiry() finds the balance on the account whose number is "acct". 74 | * If "acct" is an invalid number, returns -1. 75 | * @param acct an account number. 76 | * @return the balance, or -1 if the account number is invalid. 77 | */ 78 | public int balanceInquiry(int acct) throws BadAccountException{ 79 | AccountData account = findAccount(acct); 80 | 81 | // if (account == null) { 82 | // System.out.println("Error: Couldn't find account number `" + 83 | // acct + "'" ); 84 | // return -1; 85 | // } else { 86 | return account.getBalance(); 87 | // } 88 | } 89 | 90 | /** 91 | * findAccount() gets the AccountData object associated with account number 92 | * "acct". If "acct" does not refer to a valid account, returns null. 93 | * @param acct is an account number. 94 | * @return the AccountData object associated with the account number. 95 | */ 96 | private AccountData findAccount(int acct) throws BadAccountException{ 97 | AccountData account = (AccountData) accounts.find(acct); 98 | if(account == null){ 99 | throw new BadAccountException(acct); 100 | } 101 | return account; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /lab/lab6/sortedlist/Keyable.java: -------------------------------------------------------------------------------- 1 | /* Keyable.java */ 2 | 3 | package sortedlist; 4 | 5 | public interface Keyable { 6 | public int getKey(); 7 | public boolean lessThan(Keyable x); 8 | } 9 | -------------------------------------------------------------------------------- /lab/lab6/sortedlist/ListEnum.java: -------------------------------------------------------------------------------- 1 | /* ListEnum.java */ 2 | 3 | package sortedlist; 4 | 5 | import java.util.Enumeration; 6 | 7 | /** 8 | * The ListEnum class implements an Enumeration for singly-linked lists. 9 | * ListEnum objects are mutable. 10 | * @author Kathy Yelick 11 | **/ 12 | 13 | public class ListEnum implements Enumeration { 14 | private ListNode trav; 15 | 16 | /** 17 | * Creates a new enumeration for the elements linked with ListNodes 18 | * starting with l. Requires that there are no cycles in the list. 19 | */ 20 | public ListEnum( ListNode l ) { 21 | trav = l; 22 | } 23 | 24 | /** 25 | * Tests if this enumeration contains more elements. 26 | * @return true if this enumeration contains more elements; false otherwise 27 | */ 28 | public boolean hasMoreElements() { 29 | return (trav != null); 30 | } 31 | 32 | /** 33 | * Returns the next element of this enumeration. 34 | * Modifies the enumeration to move the enumeration past the returned 35 | * element of the list. 36 | * @return the next element of this enumeration. 37 | */ 38 | public Object nextElement() { 39 | Object retItem = trav.item; 40 | trav = trav.next; 41 | return retItem; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lab/lab6/sortedlist/ListNode.java: -------------------------------------------------------------------------------- 1 | /* ListNode.java */ 2 | 3 | package sortedlist; 4 | 5 | /** 6 | * ListNode is a class used internally by the List class. Each node in a 7 | * List is represented as a ListNode, with an item and a reference to the 8 | * next node in the list. 9 | **/ 10 | class ListNode { 11 | Keyable item; 12 | ListNode next; 13 | 14 | /** 15 | * Constructs a ListNode with item obj and next null. 16 | * @param obj will be the item in the node. 17 | **/ 18 | ListNode(Keyable obj) { 19 | item = obj; 20 | next = null; 21 | } 22 | 23 | /** 24 | * Constructs a ListNode with item obj and next n. 25 | * @param obj will be the item in the node. 26 | * @param n will be the next ListNode in the list. 27 | **/ 28 | ListNode(Keyable obj, ListNode n) { 29 | item = obj; 30 | next = n; 31 | } 32 | 33 | /** 34 | * ptrTo() returns a reference to the node at the given position. If 35 | * position < 1 or position > the number of nodes in the list, returns 36 | * null. Assumes the list is acyclic. 37 | * @return a reference to the node at position "position". 38 | */ 39 | public ListNode ptrTo(int position) { 40 | if (position < 1) { 41 | return null; 42 | } else if (position == 1) { 43 | return this; 44 | } else if (next == null) { 45 | return null; 46 | } else { 47 | return next.ptrTo(position - 1); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lab/lab6/sortedlist/SortedList.java: -------------------------------------------------------------------------------- 1 | /* SortedList.java */ 2 | 3 | package sortedlist; 4 | import java.util.Enumeration; 5 | 6 | /** 7 | * The SortedList class is a singly-linked implementation of a linked list in 8 | * sorted order. SortedLists are mutable data structures that can grow at 9 | * either end. 10 | * @author Kathy Yelick, Bob Zasio 11 | **/ 12 | public class SortedList { 13 | private int size; 14 | ListNode head; 15 | 16 | /** 17 | * Construct an empty list 18 | **/ 19 | public SortedList() { 20 | size = 0; 21 | head = null; 22 | } 23 | 24 | /** 25 | * isEmpty() returns true if this list is empty, false otherwise. 26 | * @return true if the list is empty, false otherwise. 27 | **/ 28 | public boolean isEmpty() { 29 | return (size == 0); 30 | } 31 | 32 | /** 33 | * length() returns the length of this list. 34 | * @return the length of the list. 35 | **/ 36 | public int length() { 37 | return size; 38 | } 39 | 40 | /** 41 | * insert() inserts the element x into the proper sorted location. 42 | **/ 43 | public void insert(Keyable x) { 44 | ListNode newnode = new ListNode(x, null); 45 | 46 | if (head == null) { 47 | head = newnode; 48 | } else if (!head.item.lessThan(x)) { 49 | newnode.next = head; 50 | head = newnode; 51 | } else { 52 | ListNode temp = head; 53 | while (temp.next != null) { 54 | if (!temp.next.item.lessThan(x)) { 55 | newnode.next = temp.next; 56 | temp.next = newnode; 57 | temp = temp.next; 58 | break; 59 | } 60 | temp = temp.next; 61 | } 62 | if (temp.next == null) { 63 | temp.next = newnode; 64 | } 65 | } 66 | size++; 67 | } 68 | 69 | /** 70 | * Keyable() returns the element with the given key, or null if none of the 71 | * elements have that key. 72 | **/ 73 | public Keyable find(int key) { 74 | ListNode temp = head; 75 | while (temp != null) { 76 | if (temp.item.getKey() == key) { 77 | return temp.item; 78 | } 79 | temp = temp.next; 80 | } 81 | return null; 82 | } 83 | 84 | /** 85 | * elements() returns an Enumeration of the components of this list. 86 | * @return an Enumeration of the components of this list. 87 | **/ 88 | public Enumeration elements() { 89 | return new ListEnum(head); 90 | } 91 | 92 | /** 93 | * toString() returns a String representation of this list. 94 | * @return a String representation of this list. 95 | **/ 96 | public String toString() { 97 | int i; 98 | Object obj; 99 | String result = "[ "; 100 | 101 | ListNode cur = head; 102 | 103 | while (cur != null) { 104 | obj = cur.item; 105 | result = result + obj.toString() + " "; 106 | cur = cur.next; 107 | } 108 | result = result + "]"; 109 | return result; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /lab/lab7/DebugMe.java: -------------------------------------------------------------------------------- 1 | /* DebugMe.java */ 2 | 3 | /** 4 | * DebugMe is an application for summing a geometric series. 5 | **/ 6 | class DebugMe { 7 | 8 | /** 9 | * main() prints the value of a geometric series. 10 | * @param args is ignored. 11 | **/ 12 | public static void main(String[] args) { 13 | 14 | int N = 3; 15 | ListNode geomSeries = createGeomSeries((double)1/2, N); 16 | double sum = listSum(geomSeries); 17 | 18 | System.out.println("for N = " + N + ",\n"); 19 | System.out.println(" N | 1 |^i"); 20 | System.out.println(" sum |---| = " + sum); 21 | System.out.println(" i=0 | 2 |\n"); 22 | } 23 | 24 | /** 25 | * createGeomSeries() creates a list built from ListNodes in which each item 26 | * is a Double containing one term in the geometric series 27 | * 28 | * N 29 | * sum (r^i). 30 | * i=0 31 | * 32 | * @param r is the base of the geometric series. 33 | * @param N is the maximum exponent of any term in the geometric series. 34 | * N is assumed to be non-negative. 35 | */ 36 | public static ListNode createGeomSeries(double r, int N) { 37 | ListNode newTerm = new ListNode(null, null); 38 | if (N == 0) { 39 | newTerm.item = new Double(1.0); 40 | newTerm.next = null; 41 | } else { 42 | newTerm.next = createGeomSeries(r, N - 1); 43 | newTerm.item = new Double(((Double) newTerm.next.item).doubleValue() * 44 | r); 45 | } 46 | 47 | return newTerm; 48 | } 49 | 50 | 51 | /** 52 | * listSum() computes the sum of terms in a list. 53 | * @param l is linked list represented by ListNodes. Each item in the list 54 | * is assumed to be a Double. 55 | */ 56 | public static double listSum(ListNode l) { 57 | if (l == null) { 58 | return 0.0; 59 | } 60 | 61 | return ((Double) l.item).doubleValue() + listSum(l.next); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lab/lab7/ListNode.java: -------------------------------------------------------------------------------- 1 | /* ListNode.java */ 2 | 3 | /** 4 | * ListNode is a very simple headless list class, akin to cons cells in 5 | * Scheme. Each ListNode contains an item and a reference to the next node. 6 | **/ 7 | class ListNode { 8 | 9 | public Object item; 10 | public ListNode next; 11 | 12 | /** 13 | * Constructs a ListNode with item i and next node n. 14 | * @param i the item to store in the ListNode. 15 | * @param n the next ListNode following this ListNode. 16 | **/ 17 | ListNode(Object i, ListNode n) { 18 | item = i; 19 | next = n; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /pj1/Blur.java: -------------------------------------------------------------------------------- 1 | /* Blur.java */ 2 | 3 | /* DO NOT CHANGE THIS FILE. */ 4 | /* YOUR SUBMISSION MUST WORK CORRECTLY WITH _OUR_ COPY OF THIS FILE. */ 5 | 6 | /* You may wish to make temporary changes or insert println() statements */ 7 | /* while testing your code. When you're finished testing and debugging, */ 8 | /* though, make sure your code works with the original version of this file. */ 9 | 10 | /** 11 | * The Blur class is a program that reads an image file in TIFF format, blurs 12 | * it with a 3x3 box blurring kernel, writes the blurred image as a TIFF file, 13 | * and displays both images. 14 | * 15 | * The Blur program takes up to two parameters. The first parameter is 16 | * the name of the TIFF-format file to read. (The output image file is 17 | * constructed by adding "blur_" to the beginning of the input filename.) 18 | * An optional second parameter specifies the number of iterations of the 19 | * box blurring operation. (The default is one iteration.) For example, if 20 | * you run 21 | * 22 | * java Blur engine.tiff 5 23 | * 24 | * then Blur will read engine.tiff, perform 5 iterations of blurring, and 25 | * write the blurred image to blur_engine.tiff . 26 | * 27 | * @author Joel Galenson and Jonathan Shewchuk 28 | */ 29 | 30 | public class Blur { 31 | 32 | /** 33 | * blurFile() reads a TIFF image file, blurs it, write the blurred image to 34 | * a new TIFF image file, and displays both images. 35 | * 36 | * @param filename the name of the input TIFF image file. 37 | * @param numIterations the number of iterations of blurring to perform. 38 | */ 39 | private static void blurFile(String filename, int numIterations) { 40 | System.out.println("Reading image file " + filename); 41 | PixImage image = ImageUtils.readTIFFPix(filename); 42 | 43 | System.out.println("Blurring image file."); 44 | PixImage blurred = image.boxBlur(numIterations); 45 | 46 | String blurname = "blur_" + filename; 47 | System.out.println("Writing blurred image file " + blurname); 48 | TIFFEncoder.writeTIFF(blurred, blurname); 49 | /* 50 | TIFFEncoder.writeTIFF(new RunLengthEncoding(edges), "rle" + blurname); 51 | */ 52 | 53 | System.out.println("Displaying input image and blurred image."); 54 | System.out.println("Close the image to quit."); 55 | ImageUtils.displayTIFFs(new PixImage[] { image, blurred }); 56 | } 57 | 58 | /** 59 | * main() reads the command-line arguments and initiates the blurring. 60 | * 61 | * The first command-line argument is the name of the image file. 62 | * An optional second argument is number of iterations of blurring. 63 | * 64 | * @param args the usual array of command-line argument Strings. 65 | */ 66 | public static void main(String[] args) { 67 | if (args.length == 0) { 68 | System.out.println("usage: java Blur imagefile [iterations]"); 69 | System.out.println(" imagefile is an image in TIFF format."); 70 | System.out.println(" interations is the number of blurring iterations" + 71 | " (default 1)."); 72 | System.out.println("The blurred image is written to blur_imagefile."); 73 | System.exit(0); 74 | } 75 | 76 | int numIterations = 1; 77 | if (args.length > 1) { 78 | try { 79 | numIterations = Integer.parseInt(args[1]); 80 | } catch (NumberFormatException ex) { 81 | System.err.println("The second argument must be a number."); 82 | System.exit(1); 83 | } 84 | } 85 | 86 | blurFile(args[0], numIterations); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /pj1/DList.java: -------------------------------------------------------------------------------- 1 | 2 | public class DList { 3 | 4 | protected DListNode head; 5 | protected DListNode tail; 6 | protected long size; 7 | 8 | public DList() { 9 | head = null; 10 | tail = null; 11 | size = 0; 12 | } 13 | 14 | public void insertFront(int r, int g, int b, int num) { 15 | if(size == 0) { 16 | head = new DListNode(r, g, b, num); 17 | tail = head; 18 | size++; 19 | }else { 20 | DListNode newNode = new DListNode(r, g, b, num); 21 | newNode.next = head; 22 | head.prev = newNode; 23 | head = newNode; 24 | size++; 25 | } 26 | } 27 | 28 | public void insertBack(int r, int g, int b, int num) { 29 | if(size == 0) { 30 | head = new DListNode(r, g, b, num); 31 | tail = head; 32 | size++; 33 | }else { 34 | DListNode newNode = new DListNode(r, g, b, num); 35 | newNode.prev = tail; 36 | tail.next = newNode; 37 | tail = newNode; 38 | size++; 39 | } 40 | } 41 | 42 | public void insertBetween(int r, int g, int b, int num, DListNode pre){ 43 | if(size > 1) { 44 | DListNode newNode = new DListNode(r, g, b, num); 45 | pre.next.prev = newNode; 46 | newNode.next = pre.next; 47 | newNode.prev = pre; 48 | pre.next = newNode; 49 | size++; 50 | } 51 | } 52 | 53 | public void removeFront() { 54 | if(size > 1) { 55 | head.next.prev = null; 56 | head = head.next; 57 | size--; 58 | }else if (size ==1) { 59 | head = null; 60 | tail = null; 61 | size--; 62 | } 63 | } 64 | 65 | public void removeBack() { 66 | if(size > 1) { 67 | tail.prev.next = null; 68 | tail = tail.prev; 69 | size--; 70 | }else if (size == 1) { 71 | head = null; 72 | tail = null; 73 | size--; 74 | } 75 | } 76 | 77 | public void removeBetween(DListNode pre){ 78 | if(size > 2) { 79 | pre.next = pre.next.next; 80 | pre.next.prev = pre; 81 | size--; 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /pj1/DListNode.java: -------------------------------------------------------------------------------- 1 | 2 | public class DListNode { 3 | 4 | public int r; 5 | public int g; 6 | public int b; 7 | public int num; 8 | public DListNode prev; 9 | public DListNode next; 10 | 11 | DListNode() { 12 | r = 0; 13 | g = 0; 14 | b = 0; 15 | num = 0; 16 | prev = null; 17 | next = null; 18 | } 19 | 20 | DListNode(int red, int green, int blue, int length) { 21 | r = red; 22 | g = green; 23 | b = blue; 24 | num = length; 25 | prev = null; 26 | next = null; 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /pj1/ImageUtils.java: -------------------------------------------------------------------------------- 1 | /* ImageUtils.java */ 2 | 3 | /* DO NOT CHANGE THIS FILE. */ 4 | /* YOUR SUBMISSION MUST WORK CORRECTLY WITH _OUR_ COPY OF THIS FILE. */ 5 | 6 | /* You may wish to make temporary changes or insert println() statements */ 7 | /* while testing your code. When you're finished testing and debugging, */ 8 | /* though, make sure your code works with the original version of this file. */ 9 | 10 | /** 11 | * The ImageUtils class reads and writes TIFF file, converting to and from 12 | * pixel arrays in PixImage format or run-length encodings in 13 | * RunLengthEncoding format. Methods are also included for displaying images 14 | * in PixImage format. 15 | * 16 | * @author Joel Galenson 17 | **/ 18 | 19 | import java.awt.Color; 20 | import java.awt.event.WindowAdapter; 21 | import java.awt.event.WindowEvent; 22 | import java.awt.image.BufferedImage; 23 | 24 | import javax.media.jai.JAI; 25 | import javax.media.jai.RenderedImageAdapter; 26 | import javax.swing.Box; 27 | import javax.swing.ImageIcon; 28 | import javax.swing.JFrame; 29 | import javax.swing.JLabel; 30 | 31 | /** 32 | * ImageUtils contains utilities for reading, writing, and displaying images. 33 | * 34 | * It uses JAI to read and write TIFF files, as the standard libraries cannot 35 | * read them. 36 | * 37 | * All image data is in RGB format (see BufferedImage.getRGB). 38 | */ 39 | public class ImageUtils { 40 | 41 | /** 42 | * buffer2PixImage() converts a BufferedImage to a PixImage. 43 | * @param bImage the image to convert. 44 | * @return a PixImage with the same pixels as the BufferedImage. 45 | */ 46 | private static PixImage buffer2PixImage(BufferedImage bImage) { 47 | PixImage pImage = new PixImage(bImage.getWidth(), bImage.getHeight()); 48 | for (int x = 0; x < bImage.getWidth(); x++) { 49 | for (int y = 0; y < bImage.getHeight(); y++) { 50 | Color color = new Color(bImage.getRGB(x, y)); 51 | pImage.setPixel(x, y, (short) color.getRed(), (short) color.getGreen(), 52 | (short) color.getBlue()); 53 | } 54 | } 55 | return pImage; 56 | } 57 | 58 | /** 59 | * pixImage2buffer() converts a PixImage to a BufferedImage. 60 | * @param pImage the image to convert. 61 | * @return a BufferedImage with the same pixels as the PixImage. 62 | */ 63 | static BufferedImage pixImage2buffer(PixImage pImage) { 64 | BufferedImage bImage = new BufferedImage(pImage.getWidth(), 65 | pImage.getHeight(), 66 | BufferedImage.TYPE_INT_ARGB); 67 | for (int x = 0; x < bImage.getWidth(); x++) { 68 | for (int y = 0; y < bImage.getHeight(); y++) { 69 | bImage.setRGB(x, y, new Color(pImage.getRed(x, y), 70 | pImage.getGreen(x, y), 71 | pImage.getBlue(x, y)).getRGB()); 72 | } 73 | } 74 | return bImage; 75 | } 76 | 77 | /** 78 | * readTIFF() reads an image from a file and formats it as a BufferedImage. 79 | * @param filename the name of the file to read. 80 | * @return a BufferedImage of the file 81 | */ 82 | private static BufferedImage readTIFF(String filename) { 83 | return (new RenderedImageAdapter(JAI.create("fileload", filename))) 84 | .getAsBufferedImage(); 85 | } 86 | 87 | /** 88 | * readTIFFPix() reads an image from a file and formats it as a PixImage. 89 | * @param filename the name of the file to read. 90 | * @return a PixImage of the file 91 | */ 92 | public static PixImage readTIFFPix(String filename) { 93 | return buffer2PixImage(readTIFF(filename)); 94 | } 95 | 96 | /** 97 | * readTIFFRLE() reads an image from a file and formats it as a run-length 98 | * encoding. 99 | * @param filename the name of the file to read. 100 | * @return a RunLengthEncoding of the file. 101 | */ 102 | public static RunLengthEncoding readTIFFRLE(String filename) { 103 | return new RunLengthEncoding(readTIFFPix(filename)); 104 | } 105 | 106 | /** 107 | * writeTIFF() writes a BufferedImage to a specified file in TIFF format. 108 | * @param rle the input BufferedImage. 109 | * @param filename the output filename. 110 | */ 111 | private static void writeTIFF(BufferedImage image, String filename) { 112 | JAI.create("filestore", image, filename, "tiff"); 113 | } 114 | 115 | /** 116 | * writeTIFF() writes a PixImage to a specified file in TIFF format. 117 | * @param image the input PixImage. 118 | * @param filename the output filename. 119 | */ 120 | public static void writeTIFF(PixImage image, String filename) { 121 | writeTIFF(pixImage2buffer(image), filename); 122 | } 123 | 124 | /** 125 | * writeTIFF() writes a run-length encoding to a specified file in TIFF 126 | * format. 127 | * @param rle the input run-length encoded image. 128 | * @param filename the output filename. 129 | */ 130 | public static void writeTIFF(RunLengthEncoding rle, String filename) { 131 | writeTIFF(rle.toPixImage(), filename); 132 | } 133 | 134 | /** 135 | * displayFrame displays a JFrame and pauses until the window is closed. 136 | * @param frame a JFrame to display. 137 | */ 138 | private static void displayFrame(final JFrame frame) { 139 | try { 140 | synchronized (ImageUtils.class) { 141 | frame.setResizable(false); 142 | frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 143 | frame.addWindowListener(new WindowAdapter() { 144 | @Override 145 | public void windowClosing(WindowEvent event) { 146 | synchronized (ImageUtils.class) { 147 | ImageUtils.class.notify(); 148 | frame.dispose(); 149 | } 150 | } 151 | }); 152 | frame.pack(); 153 | frame.setVisible(true); 154 | ImageUtils.class.wait(); 155 | } 156 | } catch (InterruptedException e) { 157 | System.out.println("Interrupted Exception in displayFrame()."); 158 | e.printStackTrace(); 159 | } 160 | } 161 | 162 | /** 163 | * displayTIFFs displays a sequence of PixImages and pauses until the window 164 | * is closed. 165 | * @param images an array of PixImages to display. 166 | */ 167 | public static void displayTIFFs(PixImage[] images) { 168 | JFrame frame = new JFrame(); 169 | Box box = Box.createHorizontalBox(); 170 | for (int i = 0; i < images.length; i++) { 171 | box.add(new JLabel(new ImageIcon(pixImage2buffer(images[i])))); 172 | if (i < images.length - 1) { 173 | box.add(Box.createHorizontalStrut(10)); 174 | } 175 | } 176 | frame.add(box); 177 | displayFrame(frame); 178 | } 179 | 180 | /** 181 | * displayTIFF displays a PixIamge and pauses until the window is closed. 182 | * @param image the PixImage to display. 183 | */ 184 | public static void displayTIFF(PixImage image) { 185 | displayTIFFs(new PixImage[] { image }); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /pj1/RunIterator.java: -------------------------------------------------------------------------------- 1 | /* RunIterator.java */ 2 | 3 | /** 4 | * The RunIterator class iterates over a RunLengthEncoding and allows other 5 | * classes to inspect the runs in a run-length encoding, one run at a time. 6 | * A newly constructed RunIterator "points" to the first run in the encoding 7 | * used to construct it. Each time next() is invoked, it returns a run 8 | * (represented as an array of four ints); a sequence of calls to next() 9 | * returns run in consecutive order until every run has been returned. 10 | * 11 | * Client classes should never call the RunIterator constructor directly; 12 | * instead they should invoke the iterator() method on a RunLengthEncoding 13 | * object, which will construct a properly initialized RunIterator for the 14 | * client. 15 | * 16 | * Calls to hasNext() determine whether another run is available, or whether 17 | * the iterator has reached the end of the run-length encoding. When 18 | * a RunIterator reaches the end of an encoding, it is no longer useful, and 19 | * the next() method may throw an exception; thus it is recommended to check 20 | * hasNext() before each call to next(). To iterate through the encoding 21 | * again, construct a new RunIterator by invoking iterator() on the 22 | * RunLengthEncoding and throw the old RunIterator away. 23 | * 24 | * A RunIterator is not guaranteed to work if the underlying RunLengthEncoding 25 | * is modified after the RunIterator is constructed. (Especially if it is 26 | * modified by setPixel().) 27 | */ 28 | 29 | import java.util.Iterator; 30 | import java.util.NoSuchElementException; 31 | 32 | @SuppressWarnings("rawtypes") 33 | public class RunIterator implements Iterator { 34 | 35 | /** 36 | * Define any variables associated with a RunIterator object here. 37 | * These variables MUST be private. 38 | */ 39 | protected DListNode current; 40 | 41 | 42 | 43 | 44 | /** 45 | * RunIterator() constructs a new iterator starting with a specified run. 46 | * 47 | * @param node the run where this iterator starts. 48 | */ 49 | // Unlike all the other methods we have asked you to write, the RunIterator() 50 | // constructor does not have a predefined signature, because no outside 51 | // class should ever call this constructor except the iterator() method in 52 | // the RunLengthEncoding class. The correct way for outside classes to 53 | // get access to a RunIterator is to call the iterator() method on a 54 | // RunLengthEncoding object. You are welcome to add any parameters to the 55 | // constructor that you want so that your RunLengthEncoding.iterator() 56 | // implementation can construct a RunIterator that points to the first run of 57 | // the encoding. 58 | RunIterator(DListNode current) { 59 | // Your solution here. You may add parameters to the method signature. 60 | this.current = current; 61 | } 62 | 63 | /** 64 | * hasNext() returns true if this iterator has more runs. If it returns 65 | * false, then the next call to next() may throw an exception. 66 | * 67 | * @return true if the iterator has more elements. 68 | */ 69 | public boolean hasNext() { 70 | // Replace the following line with your solution. 71 | return current != null; 72 | } 73 | 74 | /** 75 | * next() returns an array of 4 ints that specifies the current run in the 76 | * sequence. It also advances the iterator to the next run, so that the 77 | * next call to next() will return the following run. 78 | * 79 | * If "this" RunIterator has returned every run, it cannot be expected to 80 | * behave well. (Technically, it is supposed to throw a 81 | * NoSuchElementException, but we haven't learned about exceptions yet.) 82 | * 83 | * @return an array of 4 ints that specify the current run in the sequence. 84 | * The pixel count is in index [0]; the red value is in index [1]; the green 85 | * value is in index [2]; and the blue value is in index [3]. 86 | * @throws NoSuchElementException if the iteration has no more elements. 87 | * (We strongly recommend calling hasNext() to check whether there are any 88 | * more runs before calling next().) 89 | * 90 | * The returned four-int array is constructed in next(), and can be 91 | * discarded by the calling method after use. The array should not be part 92 | * of your RunLengthEncoding data structure! It must be freshly constructed 93 | * for the sole purpose of returning four ints. 94 | */ 95 | public int[] next() { 96 | // Construct a new array of 4 ints, fill in its values, and return it. 97 | // Don't forget to advance the RunIterator's pointer so that the next 98 | // call to next() will return the subsequent run. 99 | 100 | // Replace the following line with your solution. 101 | if(!hasNext()){ 102 | throw new NoSuchElementException(); 103 | } 104 | int[] four = new int[4]; 105 | four[0] = current.num; 106 | four[1] = current.r; 107 | four[2] = current.g; 108 | four[3] = current.b; 109 | current = current.next; 110 | return four; 111 | } 112 | 113 | /** 114 | * remove() would remove from the underlying run-length encoding the run 115 | * identified by this iterator, but we are NOT implementing it. 116 | * 117 | * DO NOT CHANGE THIS METHOD. 118 | */ 119 | public void remove() { 120 | throw new UnsupportedOperationException(); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /pj1/Sobel.java: -------------------------------------------------------------------------------- 1 | /* Sobel.java */ 2 | 3 | /* DO NOT CHANGE THIS FILE. */ 4 | /* YOUR SUBMISSION MUST WORK CORRECTLY WITH _OUR_ COPY OF THIS FILE. */ 5 | 6 | /* You may wish to make temporary changes or insert println() statements */ 7 | /* while testing your code. When you're finished testing and debugging, */ 8 | /* though, make sure your code works with the original version of this file. */ 9 | 10 | /** 11 | * The Sobel class is a program that reads an image file in TIFF format, 12 | * performs Sobel edge detection and uses it to create a grayscale image 13 | * showing the intensities of the strongest edges, writes the grayscale image 14 | * as a TIFF file, and displays both images. Optionally, it can also blur the 15 | * image with one or more iterations of a 3x3 box blurring kernel (similar to 16 | * our Blur program) before performing edge detection, which tends to make 17 | * edge detection more robust. If blurring is selected, this program writes 18 | * both the blurred image and the grayscale-edge image to files and displays 19 | * all three images (the input image and the two output images). 20 | * 21 | * The Sobel program takes up to three parameters. The first parameter is 22 | * the name of the TIFF-format file to read. (The output image file is 23 | * constructed by adding "edge_" to the beginning of the input filename.) 24 | * An optional second parameter specifies the number of iterations of the 25 | * box blurring operation. (The default is zero iterations.) If a third 26 | * parameter is present (regardless of what it is), a second output grayscale 27 | * image is written, run-length encoded to reduce its file size, with prefix 28 | * "rle_". For example, if you run 29 | * 30 | * java Sobel engine.tiff 5 blah 31 | * 32 | * then Sobel will read engine.tiff, perform 5 iterations of blurring, perform 33 | * Sobel edge detection, map the Sobel gradients to grayscale intensities, 34 | * write the blurred image to blur_engine.tiff, write a grayscale-edge image 35 | * to edge_engine.tiff, and write a run-length encoded grayscale-edge image to 36 | * rle_engine.tiff. 37 | * 38 | * @author Joel Galenson and Jonathan Shewchuk 39 | */ 40 | 41 | public class Sobel { 42 | 43 | /** 44 | * sobelFile() reads a TIFF image file, performs Sobel edge detection, maps 45 | * the Sobel gradients to grayscale intensities, writes the edges to a new 46 | * grayscale TIFF image file, and displays both images. Optionally, it can 47 | * blurs the image before edge detection, in which case it also writes the 48 | * blurred image to a file and display all three images. 49 | * 50 | * @param filename the name of the input TIFF image file. 51 | * @param numIterations the number of iterations of blurring to perform. 52 | * @param rle true if the output TIFF file should be run-length encoded. 53 | */ 54 | private static void sobelFile(String filename, int numIterations, 55 | boolean rle) { 56 | System.out.println("Reading image file " + filename); 57 | PixImage image = ImageUtils.readTIFFPix(filename); 58 | PixImage blurred = image; 59 | 60 | if (numIterations > 0) { 61 | System.out.println("Blurring image file."); 62 | blurred = image.boxBlur(numIterations); 63 | 64 | String blurname = "blur_" + filename; 65 | System.out.println("Writing blurred image file " + blurname); 66 | TIFFEncoder.writeTIFF(blurred, blurname); 67 | } 68 | 69 | System.out.println("Performing Sobel edge detection on image file."); 70 | PixImage sobeled = blurred.sobelEdges(); 71 | 72 | String edgename = "edge_" + filename; 73 | System.out.println("Writing grayscale-edge image file " + edgename); 74 | TIFFEncoder.writeTIFF(sobeled, edgename); 75 | if (rle) { 76 | String rlename = "rle_" + filename; 77 | System.out.println("Writing run-length encoded grayscale-edge " + 78 | "image file " + rlename); 79 | TIFFEncoder.writeTIFF(new RunLengthEncoding(sobeled), rlename); 80 | } 81 | 82 | if (numIterations > 0) { 83 | System.out.println("Displaying input image, blurred image, and " + 84 | "grayscale-edge image."); 85 | System.out.println("Close the image to quit."); 86 | ImageUtils.displayTIFFs(new PixImage[] { image, blurred, sobeled }); 87 | } else { 88 | System.out.println("Displaying input image and grayscale-edge image."); 89 | System.out.println("Close the image to quit."); 90 | ImageUtils.displayTIFFs(new PixImage[] { image, sobeled }); 91 | } 92 | } 93 | 94 | /** 95 | * main() reads the command-line arguments and initiates the blurring. 96 | * 97 | * The first command-line argument is the name of the image file. 98 | * An optional second argument is number of iterations of blurring. 99 | * An optional third argument triggers the writing of a run-length encoded 100 | * grayscale-edge image. 101 | * 102 | * @param args the usual array of command-line argument Strings. 103 | */ 104 | public static void main(String[] args) { 105 | if (args.length == 0) { 106 | System.out.println("usage: java Sobel imagefile [iterations] [RLE]"); 107 | System.out.println(" imagefile is an image in TIFF format."); 108 | System.out.println(" interations is the number of blurring iterations" + 109 | " (default 0)."); 110 | System.out.println(" any third argument (RLE) turns on run-length " + 111 | "encoding in the output file"); 112 | System.out.println("The grayscale-edge image is written to " + 113 | "edge_imagefile."); 114 | System.out.println("If blurring is selected, " + 115 | "the blurred image is written to blur_imagefile."); 116 | System.exit(0); 117 | } 118 | 119 | int numIterations = 0; 120 | if (args.length >= 2) { 121 | try { 122 | numIterations = Integer.parseInt(args[1]); 123 | } catch (NumberFormatException ex) { 124 | System.err.println("The second argument must be a number."); 125 | System.exit(1); 126 | } 127 | } 128 | 129 | sobelFile(args[0], numIterations, args.length >= 3); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /pj1/TIFF6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/TIFF6.pdf -------------------------------------------------------------------------------- /pj1/baby.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/baby.tiff -------------------------------------------------------------------------------- /pj1/black.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/black.tiff -------------------------------------------------------------------------------- /pj1/data.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/data.gz -------------------------------------------------------------------------------- /pj1/engine.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/engine.tiff -------------------------------------------------------------------------------- /pj1/feathers.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/feathers.tiff -------------------------------------------------------------------------------- /pj1/flower.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/flower.tiff -------------------------------------------------------------------------------- /pj1/highcontrast.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/highcontrast.tiff -------------------------------------------------------------------------------- /pj1/jai_codec.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/jai_codec.jar -------------------------------------------------------------------------------- /pj1/jai_core.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/jai_core.jar -------------------------------------------------------------------------------- /pj1/readme.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/readme.pdf -------------------------------------------------------------------------------- /pj1/reggie.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/reggie.tiff -------------------------------------------------------------------------------- /pj1/woman.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj1/woman.tiff -------------------------------------------------------------------------------- /pj3/KruskalTest.java: -------------------------------------------------------------------------------- 1 | /* KruskalTest.java */ 2 | 3 | /** 4 | * The KruskalTest class tests the Kruskal class. 5 | */ 6 | 7 | import graph.*; 8 | import graphalg.*; 9 | import java.util.*; 10 | 11 | public class KruskalTest { 12 | 13 | private static final int VERTICES = 10; 14 | private static final int MAXINT = 100; 15 | 16 | private static boolean tree = true; 17 | private static boolean minTree = true; 18 | 19 | public static void addRandomEdges(WUGraph g, Object[] vertArray) { 20 | int i, j; 21 | 22 | System.out.println("Adding random edges to graph."); 23 | 24 | Random random = new Random(3); // Create a "Random" object with seed 0 25 | 26 | for (i = 0; i < vertArray.length; i++) { 27 | for (j = i; j < vertArray.length; j++) { 28 | int r = random.nextInt() % MAXINT; // Between -99 and 99 29 | if (r >= 0) { 30 | g.addEdge(vertArray[i], vertArray[j], r); 31 | } 32 | } 33 | } 34 | } 35 | 36 | public static void DFS(WUGraph t, DFSVertex current, DFSVertex prev, 37 | int[] maxOnPath, int maxEdge) { 38 | Neighbors neigh; 39 | int i; 40 | 41 | current.visited = true; 42 | maxOnPath[current.number] = maxEdge; 43 | neigh = t.getNeighbors(current); 44 | if (neigh != null) { 45 | for (i = 0; i < neigh.neighborList.length; i++) { 46 | DFSVertex next = (DFSVertex) neigh.neighborList[i]; 47 | if (next.visited) { 48 | if ((next != current) && (next != prev)) { 49 | tree = false; 50 | return; 51 | } 52 | } else if (neigh.weightList[i] > maxEdge) { 53 | DFS(t, next, current, maxOnPath, neigh.weightList[i]); 54 | } else { 55 | DFS(t, next, current, maxOnPath, maxEdge); 56 | } 57 | if (!tree) { 58 | return; 59 | } 60 | } 61 | } 62 | } 63 | 64 | public static void DFSTest(WUGraph g, WUGraph t, DFSVertex[] vertArray) { 65 | int[][] maxOnPath; 66 | Neighbors neigh; 67 | int i, j; 68 | 69 | System.out.println("Testing the tree."); 70 | 71 | maxOnPath = new int[VERTICES][VERTICES]; 72 | for (i = 0; i < VERTICES; i++) { 73 | for (j = 0; j < VERTICES; j++) { 74 | vertArray[j].visited = false; 75 | } 76 | DFS(t, vertArray[i], null, maxOnPath[i], -MAXINT); 77 | for (j = 0; j < VERTICES; j++) { 78 | if (!vertArray[j].visited) { 79 | tree = false; 80 | } 81 | } 82 | if (!tree) { 83 | return; 84 | } 85 | } 86 | 87 | // for (i = 0; i < vertArray.length; i++) { 88 | // for (j = 0; j < vertArray.length; j++) { 89 | // System.out.print(" " + maxOnPath[i][j]); 90 | // } 91 | // System.out.println(); 92 | // } 93 | 94 | for (i = 0; i < VERTICES; i++) { 95 | neigh = g.getNeighbors(vertArray[i]); 96 | if (neigh != null) { 97 | for (j = 0; j < neigh.neighborList.length; j++) { 98 | int v = ((DFSVertex) neigh.neighborList[j]).number; 99 | if (neigh.weightList[j] < maxOnPath[i][v]) { 100 | minTree = false; 101 | } 102 | } 103 | } 104 | } 105 | } 106 | 107 | public static void main(String[] args) { 108 | int i, j; 109 | int score; 110 | WUGraph g, t; 111 | DFSVertex[] vertArray; 112 | 113 | System.out.println("Running minimum spanning tree test."); 114 | System.out.println("Creating empty graph."); 115 | g = new WUGraph(); 116 | 117 | System.out.println("Adding " + VERTICES + " vertices."); 118 | vertArray = new DFSVertex[VERTICES]; 119 | for (i = 0; i < VERTICES; i++) { 120 | vertArray[i] = new DFSVertex(); 121 | vertArray[i].number = i; 122 | g.addVertex(vertArray[i]); 123 | } 124 | 125 | addRandomEdges(g, vertArray); 126 | 127 | // for (i = 0; i < vertArray.length; i++) { 128 | // for (j = 0; j < vertArray.length; j++) { 129 | // if (g.isEdge(vertArray[i], vertArray[j])) { 130 | // System.out.print(" " + g.weight(vertArray[i], vertArray[j])); 131 | // } else { 132 | // System.out.print(" *"); 133 | // } 134 | // } 135 | // System.out.println(); 136 | // } 137 | 138 | System.out.println("Finding the minimum spanning tree."); 139 | t = Kruskal.minSpanTree(g); 140 | 141 | // for (i = 0; i < vertArray.length; i++) { 142 | // for (j = 0; j < vertArray.length; j++) { 143 | // if (t.isEdge(vertArray[i], vertArray[j])) { 144 | // System.out.print(" " + t.weight(vertArray[i], vertArray[j])); 145 | // } else { 146 | // System.out.print(" *"); 147 | // } 148 | // } 149 | // System.out.println(); 150 | // } 151 | 152 | DFSTest(g, t, vertArray); 153 | 154 | if (tree) { 155 | System.out.println("One point for creating a tree."); 156 | if (minTree) { 157 | System.out.println("Two points for creating a minimum spanning tree."); 158 | score = 3; 159 | } else { 160 | System.out.println("Not a minimum spanning tree."); 161 | score = 1; 162 | } 163 | } else { 164 | System.out.println("Not a tree."); 165 | score = 0; 166 | } 167 | 168 | System.out.println("Your Kruskal test score is " + score + " out of 3."); 169 | System.out.println(" (Be sure also to run WUGTest.java.)"); 170 | } 171 | } 172 | 173 | class DFSVertex { 174 | boolean visited; 175 | int number; 176 | } 177 | -------------------------------------------------------------------------------- /pj3/graph/Neighbors.java: -------------------------------------------------------------------------------- 1 | /* Neighbors.java */ 2 | 3 | /* DO NOT CHANGE THIS FILE. */ 4 | /* YOUR SUBMISSION MUST WORK CORRECTLY WITH _OUR_ COPY OF THIS FILE. */ 5 | 6 | package graph; 7 | 8 | /** 9 | * The Neighbors class is provided solely as a way to allow the method 10 | * WUGraph.getNeighbors() to return two arrays at once. Do NOT use this class 11 | * for any other purpose. 12 | * 13 | * Since this class is NOT an abstract data type, but is merely a collection of 14 | * data, all fields are public. 15 | */ 16 | 17 | public class Neighbors { 18 | public Object[] neighborList; 19 | public int[] weightList; 20 | } 21 | -------------------------------------------------------------------------------- /pj3/graph/VertexPair.java: -------------------------------------------------------------------------------- 1 | /* VertexPair.java */ 2 | 3 | package graph; 4 | 5 | /** 6 | * The VertexPair represents a pair of objects that act as vertices in a 7 | * WUGraph (weighted, undirected graph). The purpose of a VertexPair is to 8 | * act as a key for Java's hashCode() and equals() functions. It is designed 9 | * so that the order of the two objects is immaterial; (u, v) is the same as 10 | * (v, u). 11 | */ 12 | 13 | class VertexPair { 14 | protected Object object1; 15 | protected Object object2; 16 | 17 | protected VertexPair(Object o1, Object o2) { 18 | object1 = o1; 19 | object2 = o2; 20 | } 21 | 22 | /** 23 | * hashCode() returns a hashCode equal to the sum of the hashCodes of each 24 | * of the two objects of the pair, so that the order of the objects will 25 | * not affect the hashCode. Self-edges are treated differently: we don't 26 | * add an object's hashCode to itself, since the result would always be even. 27 | * We add one to the hashCode so that a self-edge will not collide with the 28 | * object itself if vertices and edges are stored in the same hash table. 29 | */ 30 | public int hashCode() { 31 | if (object1.equals(object2)) { 32 | return object1.hashCode() + 1; 33 | } else { 34 | return object1.hashCode() + object2.hashCode(); 35 | } 36 | } 37 | 38 | /** 39 | * equals() returns true if this VertexPair represents the same unordered 40 | * pair of objects as the parameter "o". The order of the pair does not 41 | * affect the equality test, so (u, v) is found to be equal to (v, u). 42 | */ 43 | public boolean equals(Object o) { 44 | if (o instanceof VertexPair) { 45 | return ((object1.equals(((VertexPair) o).object1)) && 46 | (object2.equals(((VertexPair) o).object2))) || 47 | ((object1.equals(((VertexPair) o).object2)) && 48 | (object2.equals(((VertexPair) o).object1))); 49 | } else { 50 | return false; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /pj3/graph/WUGraph.java: -------------------------------------------------------------------------------- 1 | /* WUGraph.java */ 2 | 3 | package graph; 4 | 5 | /** 6 | * The WUGraph class represents a weighted, undirected graph. Self-edges are 7 | * permitted. 8 | */ 9 | 10 | public class WUGraph { 11 | 12 | /** 13 | * WUGraph() constructs a graph having no vertices or edges. 14 | * 15 | * Running time: O(1). 16 | */ 17 | public WUGraph(); 18 | 19 | /** 20 | * vertexCount() returns the number of vertices in the graph. 21 | * 22 | * Running time: O(1). 23 | */ 24 | public int vertexCount(); 25 | 26 | /** 27 | * edgeCount() returns the total number of edges in the graph. 28 | * 29 | * Running time: O(1). 30 | */ 31 | public int edgeCount(); 32 | 33 | /** 34 | * getVertices() returns an array containing all the objects that serve 35 | * as vertices of the graph. The array's length is exactly equal to the 36 | * number of vertices. If the graph has no vertices, the array has length 37 | * zero. 38 | * 39 | * (NOTE: Do not return any internal data structure you use to represent 40 | * vertices! Return only the same objects that were provided by the 41 | * calling application in calls to addVertex().) 42 | * 43 | * Running time: O(|V|). 44 | */ 45 | public Object[] getVertices(); 46 | 47 | /** 48 | * addVertex() adds a vertex (with no incident edges) to the graph. 49 | * The vertex's "name" is the object provided as the parameter "vertex". 50 | * If this object is already a vertex of the graph, the graph is unchanged. 51 | * 52 | * Running time: O(1). 53 | */ 54 | public void addVertex(Object vertex); 55 | 56 | /** 57 | * removeVertex() removes a vertex from the graph. All edges incident on the 58 | * deleted vertex are removed as well. If the parameter "vertex" does not 59 | * represent a vertex of the graph, the graph is unchanged. 60 | * 61 | * Running time: O(d), where d is the degree of "vertex". 62 | */ 63 | public void removeVertex(Object vertex); 64 | 65 | /** 66 | * isVertex() returns true if the parameter "vertex" represents a vertex of 67 | * the graph. 68 | * 69 | * Running time: O(1). 70 | */ 71 | public boolean isVertex(Object vertex); 72 | 73 | /** 74 | * degree() returns the degree of a vertex. Self-edges add only one to the 75 | * degree of a vertex. If the parameter "vertex" doesn't represent a vertex 76 | * of the graph, zero is returned. 77 | * 78 | * Running time: O(1). 79 | */ 80 | public int degree(Object vertex); 81 | 82 | /** 83 | * getNeighbors() returns a new Neighbors object referencing two arrays. The 84 | * Neighbors.neighborList array contains each object that is connected to the 85 | * input object by an edge. The Neighbors.weightList array contains the 86 | * weights of the corresponding edges. The length of both arrays is equal to 87 | * the number of edges incident on the input vertex. If the vertex has 88 | * degree zero, or if the parameter "vertex" does not represent a vertex of 89 | * the graph, null is returned (instead of a Neighbors object). 90 | * 91 | * The returned Neighbors object, and the two arrays, are both newly created. 92 | * No previously existing Neighbors object or array is changed. 93 | * 94 | * (NOTE: In the neighborList array, do not return any internal data 95 | * structure you use to represent vertices! Return only the same objects 96 | * that were provided by the calling application in calls to addVertex().) 97 | * 98 | * Running time: O(d), where d is the degree of "vertex". 99 | */ 100 | public Neighbors getNeighbors(Object vertex); 101 | 102 | /** 103 | * addEdge() adds an edge (u, v) to the graph. If either of the parameters 104 | * u and v does not represent a vertex of the graph, the graph is unchanged. 105 | * The edge is assigned a weight of "weight". If the graph already contains 106 | * edge (u, v), the weight is updated to reflect the new value. Self-edges 107 | * (where u.equals(v)) are allowed. 108 | * 109 | * Running time: O(1). 110 | */ 111 | public void addEdge(Object u, Object v, int weight); 112 | 113 | /** 114 | * removeEdge() removes an edge (u, v) from the graph. If either of the 115 | * parameters u and v does not represent a vertex of the graph, the graph 116 | * is unchanged. If (u, v) is not an edge of the graph, the graph is 117 | * unchanged. 118 | * 119 | * Running time: O(1). 120 | */ 121 | public void removeEdge(Object u, Object v); 122 | 123 | /** 124 | * isEdge() returns true if (u, v) is an edge of the graph. Returns false 125 | * if (u, v) is not an edge (including the case where either of the 126 | * parameters u and v does not represent a vertex of the graph). 127 | * 128 | * Running time: O(1). 129 | */ 130 | public boolean isEdge(Object u, Object v); 131 | 132 | /** 133 | * weight() returns the weight of (u, v). Returns zero if (u, v) is not 134 | * an edge (including the case where either of the parameters u and v does 135 | * not represent a vertex of the graph). 136 | * 137 | * (NOTE: A well-behaved application should try to avoid calling this 138 | * method for an edge that is not in the graph, and should certainly not 139 | * treat the result as if it actually represents an edge with weight zero. 140 | * However, some sort of default response is necessary for missing edges, 141 | * so we return zero. An exception would be more appropriate, but also more 142 | * annoying.) 143 | * 144 | * Running time: O(1). 145 | */ 146 | public int weight(Object u, Object v); 147 | 148 | } 149 | -------------------------------------------------------------------------------- /pj3/graphalg/Kruskal.java: -------------------------------------------------------------------------------- 1 | /* Kruskal.java */ 2 | 3 | package graphalg; 4 | 5 | import graph.*; 6 | import set.*; 7 | 8 | /** 9 | * The Kruskal class contains the method minSpanTree(), which implements 10 | * Kruskal's algorithm for computing a minimum spanning tree of a graph. 11 | */ 12 | 13 | public class Kruskal { 14 | 15 | /** 16 | * minSpanTree() returns a WUGraph that represents the minimum spanning tree 17 | * of the WUGraph g. The original WUGraph g is NOT changed. 18 | * 19 | * @param g The weighted, undirected graph whose MST we want to compute. 20 | * @return A newly constructed WUGraph representing the MST of g. 21 | */ 22 | public static WUGraph minSpanTree(WUGraph g); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /pj3/pj3graph.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj3/pj3graph.pdf -------------------------------------------------------------------------------- /pj3/readme.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildgood/CS61B/48599076114d1bc4586049f22821d8dd48401f1d/pj3/readme.pdf -------------------------------------------------------------------------------- /pj3/set/DisjointSets.java: -------------------------------------------------------------------------------- 1 | /* DisjointSets.java */ 2 | 3 | package set; 4 | 5 | /** 6 | * A disjoint sets ADT. Performs union-by-size and path compression. 7 | * Implemented using arrays. There is no error checking whatsoever. 8 | * By adding your own error-checking, you might save yourself a lot of time 9 | * finding bugs in your application code for Project 3 and Homework 9. 10 | * Without error-checking, expect bad things to happen if you try to unite 11 | * two elements that are not roots of their respective sets, or are not 12 | * distinct. 13 | * 14 | * Elements are represented by ints, numbered from zero. 15 | **/ 16 | 17 | public class DisjointSets { 18 | 19 | private int[] array; 20 | 21 | /** 22 | * Construct a disjoint sets object. 23 | * 24 | * @param numElements the initial number of elements--also the initial 25 | * number of disjoint sets, since every element is initially in its own set. 26 | **/ 27 | public DisjointSets(int numElements) { 28 | array = new int [numElements]; 29 | for (int i = 0; i < array.length; i++) { 30 | array[i] = -1; 31 | } 32 | } 33 | 34 | /** 35 | * union() unites two disjoint sets into a single set. A union-by-size 36 | * heuristic is used to choose the new root. This method will corrupt 37 | * the data structure if root1 and root2 are not roots of their respective 38 | * sets, or if they're identical. 39 | * 40 | * @param root1 the root of the first set. 41 | * @param root2 the root of the other set. 42 | **/ 43 | public void union(int root1, int root2) { 44 | if (array[root2] < array[root1]) { // root2 has larger tree 45 | array[root2] += array[root1]; // update # of items in root2's tree 46 | array[root1] = root2; // make root2 new root 47 | } else { // root1 has equal or larger tree 48 | array[root1] += array[root2]; // update # of items in root1's tree 49 | array[root2] = root1; // make root1 new root 50 | } 51 | } 52 | 53 | /** 54 | * find() finds the (int) name of the set containing a given element. 55 | * Performs path compression along the way. 56 | * 57 | * @param x the element sought. 58 | * @return the set containing x. 59 | **/ 60 | public int find(int x) { 61 | if (array[x] < 0) { 62 | return x; // x is the root of the tree; return it 63 | } else { 64 | // Find out who the root is; compress path by making the root x's parent. 65 | array[x] = find(array[x]); 66 | return array[x]; // Return the root 67 | } 68 | } 69 | 70 | /** 71 | * main() is test code. All the find()s on the same output line should be 72 | * identical. 73 | **/ 74 | public static void main(String[] args) { 75 | int NumElements = 128; 76 | int NumInSameSet = 16; 77 | 78 | DisjointSets s = new DisjointSets(NumElements); 79 | int set1, set2; 80 | 81 | for (int k = 1; k < NumInSameSet; k *= 2) { 82 | for (int j = 0; j + k < NumElements; j += 2 * k) { 83 | set1 = s.find(j); 84 | set2 = s.find(j + k); 85 | s.union(set1, set2); 86 | } 87 | } 88 | 89 | for (int i = 0; i < NumElements; i++) { 90 | System.out.print(s.find(i) + "*"); 91 | if (i % NumInSameSet == NumInSameSet - 1) { 92 | System.out.println(); 93 | } 94 | } 95 | System.out.println(); 96 | } 97 | } 98 | --------------------------------------------------------------------------------