diff --git a/a2/src/edu/wmich/cs3310/a2/Controller.java b/a2/src/edu/wmich/cs3310/a2/Controller.java index c372e44674a1d784533254bef2b325d949f8d53b..86db3c6aeb1345be71b8855e19686013d761def2 100644 --- a/a2/src/edu/wmich/cs3310/a2/Controller.java +++ b/a2/src/edu/wmich/cs3310/a2/Controller.java @@ -19,16 +19,16 @@ public class Controller { private String nameString; private Random random = new Random(); private Scanner reader = new Scanner(System.in); - char[] bubbleArray; - char[] selectArray; - char[] mergeArray; - char[] insertArray; - char[] bInsertArray; - CharQueue bubbleList = new CharQueue(); - CharQueue selectList = new CharQueue(); - CharQueue mergeList = new CharQueue(); - CharQueue insertList = new CharQueue(); - CharQueue bInsertList = new CharQueue(); + private char[] bubbleArray; + private char[] selectArray; + private char[] mergeArray; + private char[] insertArray; + private char[] bInsertArray; + private CharQueue bubbleList = new CharQueue(); + private CharQueue selectList = new CharQueue(); + private CharQueue mergeList = new CharQueue(); + private CharQueue insertList = new CharQueue(); + private CharQueue bInsertList = new CharQueue(); //endregion Variables @@ -58,6 +58,7 @@ public class Controller { nameString = GetUserInput("Enter a name: "); PopulateData(); + PrintAllDataStructures(); SortAllDataStructures(); PrintAllDataStructures(); } @@ -115,65 +116,519 @@ public class Controller { * Calls sorting on all available data structures. */ protected void SortAllDataStructures() { + System.out.println("Sorting..."); ArrayBubbleSort(); ListBubbleSort(); ArraySelectionSort(); ListSelectionSort(); - ArrayMergeSort(); - ListMergeSort(); + ArrayMergeSort(0, (charNumber - 1)); + mergeList = ListMergeSort(mergeList,0, (charNumber - 1)); ArrayInsertionSort(); ListInsertionSort(); ArrayBinaryInsertionSort(); ListBinaryInsertionSort(); } - protected void ArrayBubbleSort() { + /** + * Calls bubble sort on appropriate array. + */ + protected void ArrayBubbleSort() { + int index = 0; + int maxIndex = charNumber; + boolean wasSorted = true; + char tempChar; + + // Loop until one iteration does NOT change values. + while (wasSorted) { + wasSorted = false; + + // Loop through all unsorted values. + while (index < (maxIndex - 1)) { + // Check current and next values. + if (bubbleArray[index] > bubbleArray[index + 1]) { + tempChar = bubbleArray[index]; + bubbleArray[index] = bubbleArray[index + 1]; + bubbleArray[index + 1] = tempChar; + wasSorted = true; + } + index++; + } + index = 0; + maxIndex--; + } } + /** + * Calls bubble sort on appropriate linked list. + */ protected void ListBubbleSort() { - + boolean wasSorted = true; + char tempChar; + CharNode currentNode = bubbleList.headNode(); + CharNode lastUnsortedNode = bubbleList.tailNode(); + + // Loop until one iteration does NOT change values. + while (wasSorted) { + wasSorted = false; + + // Loop through all unsorted values. + while (currentNode != lastUnsortedNode) { + // Check current and next values. + if (currentNode.myData() > currentNode.nextNode().myData()) { + tempChar = currentNode.myData(); + currentNode.myData(currentNode.nextNode().myData()); + currentNode.nextNode().myData(tempChar); + wasSorted = true; + } + currentNode = currentNode.nextNode(); + } + currentNode = bubbleList.headNode(); + lastUnsortedNode = lastUnsortedNode.prevNode(); + } } + /** + * Calls selection sort on appropriate linked list. + */ protected void ArraySelectionSort() { + int index; + int currentIndex; + int selectedIndex; + int lastUnsortedIndex = (charNumber - 1); + char tempChar; + char[] tempArray = new char[charNumber]; + + // Loop until all values are sorted. + while (lastUnsortedIndex > 0) { + selectedIndex = 0; + currentIndex = 1; + + // Find index of "highest" letter. + for (index = 0; index < lastUnsortedIndex; index++) { + + // Compare values. + if (selectArray[currentIndex] > selectArray[selectedIndex]) { + selectedIndex = currentIndex; + } + currentIndex++; + } + // Move found value to end of "unsorted" values. + tempChar = selectArray[lastUnsortedIndex]; + selectArray[lastUnsortedIndex] = selectArray[selectedIndex]; + selectArray[selectedIndex] = tempChar; + lastUnsortedIndex--; + } } + /** + * Calls selection sort on appropriate linked list. + */ protected void ListSelectionSort() { + int currentIndex; + int selectedIndex; + CharNode tempNode; + CharNode currentNode; + CharNode selectedNode; + CharQueue tempQueue = new CharQueue(); + + // Loop until all values are sorted. + while (selectList.headNode() != null) { + selectedIndex = 0; + currentIndex = 1; + selectedNode = selectList.headNode(); + currentNode = selectedNode.nextNode(); + + // Find node of "highest" letter. + while(currentNode != null) { + + // Compare values. + if (currentNode.myData() < selectedNode.myData()) { + selectedIndex = currentIndex; + selectedNode = currentNode; + } + currentIndex++; + currentNode = currentNode.nextNode(); + } + // Remove found node and add to new "sorted" list. + tempNode = selectList.Delete(selectedIndex); + tempQueue.Enqueue(tempNode.myData()); + } + + selectList = tempQueue; } - protected void ArrayMergeSort() { + /** + * Calls merge sort on appropriate linked list. + */ + protected void ArrayMergeSort(int lowIndex, int highIndex) { + // Base case. If equal or less, back out of recursion. + if (highIndex <= lowIndex) { + return; + } + // Divide in half and recursively call self on each half. Merge together when done. + int midIndex = (lowIndex + highIndex) / 2; + ArrayMergeSort(lowIndex, midIndex); + ArrayMergeSort((midIndex + 1), highIndex); + MergeArray(lowIndex, midIndex, highIndex); } - protected void ListMergeSort() { + /** + * Handles actually merging array parts back together. + * @param lowIndex Starting index of first half. + * @param midIndex Ending index of first half/starting index of second half. + * @param highIndex Ending index of second half. + */ + protected void MergeArray(int lowIndex, int midIndex, int highIndex) { + int index; + int leftHolder = lowIndex; + int rightHolder = midIndex + 1; + char[] tempArray = new char[charNumber]; + + // Duplicate array. + for (index = lowIndex; index <= highIndex; index++) { + tempArray[index] = mergeArray[index]; + } + // Loop until all passed indexes have been looked at. + for (index = lowIndex; index <= highIndex; index++) { + + // Check if left side is done but right is not. + if (leftHolder > midIndex) { + mergeArray[index] = tempArray[rightHolder]; + rightHolder++; + } else { + // Check if right side is done but left is not. + if (rightHolder > highIndex) { + mergeArray[index] = tempArray[leftHolder]; + leftHolder++; + } else { + // Both sides not done. Compare left and right holder values. + if (tempArray[leftHolder] > tempArray[rightHolder]) { + mergeArray[index] = tempArray[rightHolder]; + rightHolder++; + } else { + mergeArray[index] = tempArray[leftHolder]; + leftHolder++; + } + } + } + } } - protected void ArrayInsertionSort() { + /** + * Calls merge sort on appropriate linked list. + * @param unsortedQueue Queue to sort. + * @param lowIndex Lowest index for given queue section. + * @param highIndex Highest index for given queue section. + * @return + */ + protected CharQueue ListMergeSort(CharQueue unsortedQueue, int lowIndex, int highIndex) { + int index; + int midIndex; + CharNode tempNode; + CharQueue firstHalf = new CharQueue(); + CharQueue secondHalf = new CharQueue(); + CharQueue sortedQueue; + // Base Case. If list is only one node large, back out of recursion. + if ((unsortedQueue.headNode() == null) || (unsortedQueue.headNode().nextNode() == null)) { + return unsortedQueue; + } + + // Divide in half and recursively call self on each half. Merge together when done. + midIndex = (lowIndex + highIndex) / 2; + + // Left half. + tempNode = mergeList.Retrieve(lowIndex); + for (index = 0; index < ((midIndex + 1) - lowIndex); index++) { + + firstHalf.Enqueue(tempNode.myData()); + tempNode = tempNode.nextNode(); + } + + // Right half. + tempNode = mergeList.Retrieve(midIndex + 1); + for (index = 0; index < (highIndex - midIndex); index++) { + secondHalf.Enqueue(tempNode.myData()); + tempNode = tempNode.nextNode(); + } + firstHalf = ListMergeSort(firstHalf, lowIndex, midIndex); + secondHalf = ListMergeSort(secondHalf, (midIndex + 1), highIndex); + sortedQueue = MergeList(firstHalf, secondHalf, lowIndex, midIndex, highIndex); + + return sortedQueue; } - protected void ListInsertionSort() { + /** + * Handles actually merging list parts back together. + * @param firstHalf First queue section to merge. + * @param secondHalf Second queue section to merge. + * @param lowIndex Starting index of first half. + * @param midIndex Ending index of first half/starting index of second half. + * @param highIndex Ending index of second half. + */ + protected CharQueue MergeList(CharQueue firstHalf, CharQueue secondHalf, int lowIndex, int midIndex, int highIndex) { + CharNode tempNode; + CharQueue sortedQueue = new CharQueue(); + + // Loop until all passed values have been looked at. + while ((firstHalf.headNode()) != null || (secondHalf.headNode() != null)) { + + // Check if left side is done but right is not. + if (firstHalf.headNode() == null) { + tempNode = secondHalf.Dequeue(); + sortedQueue.Enqueue(tempNode.myData()); + } else { + // Check if right side is done but left is not. + if (secondHalf.headNode() == null) { + tempNode = firstHalf.Dequeue(); + sortedQueue.Enqueue(tempNode.myData()); + } else { + // Both sides not done. compare left and right values. + if (firstHalf.headNode().myData() > secondHalf.headNode().myData()) { + tempNode = secondHalf.Dequeue(); + sortedQueue.Enqueue(tempNode.myData()); + } else { + tempNode = firstHalf.Dequeue(); + sortedQueue.Enqueue(tempNode.myData()); + } + } + } + } + return sortedQueue; + } + + + /** + * Calls insertion sort on appropriate linked list. + */ + protected void ArrayInsertionSort() { + int currentIndex; + int tempIndex; + int highestIndex = 0; + char tempChar; + + // Loop until all values are sorted. + for (currentIndex = 1; currentIndex < charNumber; currentIndex++) { + + // Compare values. Continually loop until 0 index is reached or proper order is found. + tempIndex = highestIndex; + while ((currentIndex > 0) && (insertArray[currentIndex] < insertArray[tempIndex])) { + tempChar = insertArray[currentIndex]; + insertArray[currentIndex] = insertArray[tempIndex]; + insertArray[tempIndex] = tempChar; + tempIndex--; + currentIndex--; + } + highestIndex++; + currentIndex = highestIndex; + } } + /** + * Calls insertion sort on appropriate linked list. + */ + protected void ListInsertionSort() { + int currentIndex; + char tempChar; + CharNode currentNode = insertList.headNode().nextNode(); + CharNode tempNode; + CharNode highestNode = insertList.headNode(); + + // Loop until all values are sorted. + for (currentIndex = 1; currentIndex < charNumber; currentIndex++) { + // Compare values. Continually loop until null pointer or proper order is found. + tempNode = highestNode; + while ((currentNode.prevNode() != null) && (currentNode.myData() < tempNode.myData())) { + tempChar = currentNode.myData(); + currentNode.myData(tempNode.myData()); + tempNode.myData(tempChar); + tempNode = tempNode.prevNode(); + currentNode = currentNode.prevNode(); + } + highestNode = highestNode.nextNode(); + currentNode = highestNode.nextNode(); + } + } + + + /** + * Calls binary insertion sort on appropriate linked list. + */ protected void ArrayBinaryInsertionSort() { + int currentIndex; + int highestIndex = 0; + + // Loop until all values are sorted. + for (currentIndex = 1; currentIndex < charNumber; currentIndex++) { + // Compare values. If difference is found, call binary insert. + if (bInsertArray[currentIndex] < bInsertArray[highestIndex]) { + ArrayBinaryInsert(0, currentIndex); + } + highestIndex++; + } } - + + /** + * Binary search and insert for putting current value into sorted values. + * Note that the high index should actually be the value to insert. + * @param lowIndex The lower bound for array section. + * @param highIndex The higher bound for array section. + */ + protected void ArrayBinaryInsert(int lowIndex, int highIndex) { + int tempIndex; + int midIndex; + char tempChar; + + // Check if end of search. + if (lowIndex >= highIndex) { + + // End of search. + tempChar = bInsertArray[highIndex]; + tempIndex = highIndex; + + // Insert value at appropriate location. + if (bInsertArray[lowIndex] > tempChar) { + bInsertArray[tempIndex] = bInsertArray[lowIndex]; + tempIndex--; + } + bInsertArray[tempIndex] = tempChar; + + } else { + + // Still more values to search. Handle accordingly. + midIndex = (lowIndex + highIndex) / 2; + + // Check for value match. + if (bInsertArray[midIndex] == bInsertArray[highIndex]) { + tempChar = bInsertArray[highIndex]; + tempIndex = highIndex; + while (tempIndex > midIndex) { + bInsertArray[tempIndex] = bInsertArray[tempIndex - 1]; + tempIndex--; + } + bInsertArray[midIndex] = tempChar; + + } else { + if (bInsertArray[midIndex] > bInsertArray[highIndex]) { + + // Move all prior values down by one since second half of list was eliminated. + tempIndex = highIndex; + tempChar = bInsertArray[highIndex]; + while (tempIndex > midIndex) { + bInsertArray[tempIndex] = bInsertArray[tempIndex - 1]; + tempIndex--; + } + bInsertArray[midIndex] = tempChar; + ArrayBinaryInsert(lowIndex, midIndex); + + } else { + ArrayBinaryInsert((midIndex + 1), highIndex); + } + } + } + } + + + /** + * Calls binary insertion sort on appropriate linked list. + */ protected void ListBinaryInsertionSort() { + int currentIndex; + CharNode currentNode = bInsertList.headNode().nextNode(); + CharNode highestNode = bInsertList.headNode(); + + // Loop until all values are sorted. + for (currentIndex = 1; currentIndex < charNumber; currentIndex++) { + // Compare values. Continually loop until null pointer or proper order is found. + if (currentNode.myData() < highestNode.myData()) { + ListBinaryInsert(bInsertList.headNode(), currentNode, 0, currentIndex); + } + highestNode = highestNode.nextNode(); + currentNode = highestNode.nextNode(); + } + } + + /** + * Binary search and insert for putting current value into sorted values. + * Note that the high index should actually be the value to insert. + * @param lowNode The lower bound for list section. + * @param highNode The upper bound for list section. + * @param lowIndex The node number of the lower bound. + * @param highIndex The node number of the upper bound. + */ + protected void ListBinaryInsert(CharNode lowNode, CharNode highNode, int lowIndex, int highIndex) { + int index; + int midIndex; + char tempChar; + CharNode midNode; + + // Check if end of search. + if (lowNode == highNode) { + + // End of search. + tempChar = highNode.myData(); + + // Insert value at appropriate location. + if (lowNode.myData() > tempChar) { + lowNode.nextNode().myData(lowNode.myData()); + highNode = highNode.prevNode(); + } + highNode.myData(tempChar); + + } else { + + // Still more values to search. Handle accordingly. + midIndex = (lowIndex + highIndex) / 2; + midNode = lowNode; + for (index = lowIndex; index < midIndex; index++) { + midNode = midNode.nextNode(); + } + + // Check for value match. + if (midNode.myData() == highNode.myData()) { + + tempChar = highNode.myData(); + while (highNode != midNode.nextNode()) { + highNode.myData(highNode.prevNode().myData()); + highNode = highNode.prevNode(); + } + midNode.nextNode().myData(tempChar); + ListBinaryInsert(lowNode, midNode, lowIndex, midIndex); + + } else { + if (midNode.myData() > highNode.myData()) { + + // Move all prior values down by one since second half of list was eliminated. + tempChar = highNode.myData(); + while (highNode != midNode) { + highNode.myData(highNode.prevNode().myData()); + highNode = highNode.prevNode(); + } + midNode.myData(tempChar); + ListBinaryInsert(lowNode, midNode, lowIndex, midIndex); + + } else { + ListBinaryInsert((midNode.nextNode()), highNode, (midIndex + 1), highIndex); + } + } + } } //endregion Sorting Methods @@ -226,13 +681,13 @@ public class Controller { index = 0; tempNode = bubbleList.headNode(); System.out.println("Bubble Sorts:"); - System.out.print("Array: "); + System.out.print(" Array: "); while (index < charNumber) { System.out.print(" " + bubbleArray[index]); index++; } System.out.println(); - System.out.print("List: "); + System.out.print(" List: "); while (tempNode != null) { System.out.print(" " + tempNode.myData()); tempNode = tempNode.nextNode(); @@ -244,13 +699,13 @@ public class Controller { index = 0; tempNode = selectList.headNode(); System.out.println("Selection Sorts:"); - System.out.print("Array: "); + System.out.print(" Array: "); while (index < charNumber) { System.out.print(" " + selectArray[index]); index++; } System.out.println(); - System.out.print("List: "); + System.out.print(" List: "); while (tempNode != null) { System.out.print(" " + tempNode.myData()); tempNode = tempNode.nextNode(); @@ -262,13 +717,13 @@ public class Controller { index = 0; tempNode = mergeList.headNode(); System.out.println("Merge Sorts:"); - System.out.print("Array: "); + System.out.print(" Array: "); while (index < charNumber) { System.out.print(" " + mergeArray[index]); index++; } System.out.println(); - System.out.print("List: "); + System.out.print(" List: "); while (tempNode != null) { System.out.print(" " + tempNode.myData()); tempNode = tempNode.nextNode(); @@ -280,13 +735,13 @@ public class Controller { index = 0; tempNode = insertList.headNode(); System.out.println("Insertion Sorts:"); - System.out.print("Array: "); + System.out.print(" Array: "); while (index < charNumber) { System.out.print(" " + insertArray[index]); index++; } System.out.println(); - System.out.print("List: "); + System.out.print(" List: "); while (tempNode != null) { System.out.print(" " + tempNode.myData()); tempNode = tempNode.nextNode(); @@ -298,13 +753,13 @@ public class Controller { index = 0; tempNode = bInsertList.headNode(); System.out.println("Binary Insertion Sorts:"); - System.out.print("Array: "); + System.out.print(" Array: "); while (index < charNumber) { System.out.print(" " + bInsertArray[index]); index++; } System.out.println(); - System.out.print("List: "); + System.out.print(" List: "); while (tempNode != null) { System.out.print(" " + tempNode.myData()); tempNode = tempNode.nextNode();