0
点赞
收藏
分享

微信扫一扫

Java-15

佳简诚锄 2022-04-29 阅读 76

学习来源:日撸 Java 三百行(41-50天,查找与排序)_闵帆的博客-CSDN博客

48 堆排序

48.1 堆排序可能是排序算法中最难的. 用到了二叉树.

48.2 建初始堆比较费劲.

48.3 调整堆的时间复杂度为O(logn), 所以总体时间复杂度只有 O(nlogn).

48.4 空间复杂度只有O(1).

代码:

	/**
	 *******************
	 * Test the method.
	 *******************
	 */
	public static void selectionSortTest() {
		int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
		String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
		DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
		
		System.out.println(tempDataArray);
		
		tempDataArray.selectionSort();
		System.out.println("Result\r\n" + tempDataArray);
		
	} //Of selectionSortTest
	
	/**
	 *******************
	 * Heap sort. Maybe the most difficult sorting algorithm.
	 *******************
	 */
	public void heapSort() {
		DataNode tempNode;
		// Step 1. Construct the initial heap.
		for (int i = length / 2; i >= 0; i--) {
			adjustHeap(i, length);
		} // Of for i
		System.out.println("The initial heap: " + this + "\r\n");
		
		// Step 2. Swap and reconstruct.
		for (int i = length - 1; i > 0; i--) {
			tempNode = data[0];
			data[0] = data[i];
			data[i] = tempNode;
			
			adjustHeap(0,i);
			System.out.println("Round " + (length - i) + ": " + this);
		} // Of for i
	} // Of heapSort
	
	/**
	 *******************
	 * Adjust the heap.
	 * 
	 * @param paraStart   The start of the index.
	 * @param paraLength  The length of the adjusted sequence.
	 *******************
	 */
	public void adjustHeap(int paraStart, int paraLength) {
		DataNode tempNode = data[paraStart];
		int tempParent = paraStart;
		int tempKey = data[paraStart].key;
		
		for (int tempChild = paraStart * 2 + 1; tempChild < paraLength; tempChild = tempChild * 2 + 1) {
			// The right child is bigger.
			if (tempChild + 1 < paraLength) {
				if (data[tempChild].key < data[tempChild + 1].key) {
					tempChild++;
				} // Of if
			} // Of if
			
			System.out.println("The parent position is " + tempParent + " and the child is " + tempChild);
			if (tempKey < data[tempChild].key) {
				// The child is bigger.
				data[tempParent] = data[tempChild];
				System.out.println("Move " + data[tempChild].key + "to position " + tempParent);
				tempParent = tempChild;
			} else {
				break;
			} // Of if
		} // Of for tempChild
		
		data[tempParent] = tempNode;
		
		System.out.println("Adjust " + paraStart + " to " + paraLength + ": " + this);
	} // Of adjustHeap
	
	/**
	 *******************
	 * Test the method.
	 *******************
	 */
	public static void heapSortTest() {
		int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
		String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
		DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
		
		System.out.println(tempDataArray);
		
		tempDataArray.heapSort();
		System.out.println("Result\r\n" + tempDataArray);
		
	} // Of heapSortTest
	
	
	/**
	 *********************
	 * The entrance of the program.
	 * 
	 * @param args
	 *            Not used now.
	 *********************
	 */
	public static void main(String[] args) {
		System.out.println("\r\n-------------sequentialSearchTest-------------");
		sequentialSearchTest();
		
		System.out.println("\r\n-------------binarySearchTest-------------");
		binarySearchTest();
		
		System.out.println("\r\n-------------hashSearchTest-------------");
		hashSearchTest();
		
		System.out.println("\r\n-------------insertionSort-------------");
		insertionSortTest();
		
		System.out.println("\r\n-------------shellSort-------------");
		shellSortTest();
		
		System.out.println("\r\n-------------bubbleSort-------------");
		bubbleSortTest();
		
		System.out.println("\r\n-------------quickSort-------------");
		quickSortTest();
		
		System.out.println("\r\n-------------selectionSort-------------");
		selectionSortTest();
		
		System.out.println("\r\n-------------heapSort-------------");
		heapSortTest();
		
	} // Of main
	

截图:

49 天: 归并排序

49.1 logn 轮, 每轮O(n) 次拷贝. 因此时间复杂度为O(nlogn).

49.2 空间复杂度为O(n). 只需要一行辅助空间.

49.3 全都是在拷贝引用, 而不是数据本身. 这是 Java 的特性.

49.4 里面的两重循环总共只有O(n). 这里是分成了若干个小组.

49.5 归并两个有序小组的时候, 用了三个并列的循环.

49.6 涉及分组后尾巴的各种情况, 所以需要相应的 if 语句.

代码:

	
	/**
	 *******************
	 * Merge Sort. Results are stored in the member variable data.
	 *******************
	 */
	public void mergeSort() {
		// Step 1. Allocate space.
		
		int tempRow; // The current row
		int tempGroups; // Number of groups
		int tempActualRow; // Only 0 or 1
		int tempNextRow = 0;
		int tempGroupNumber;
		int tempFirstStart, tempSecondStart, tempSecondEnd;
		int tempFirstIndex, tempSecondIndex;
		int tempNumCopied;
		for (int i = 0; i < length; i++) {
			System.out.println(data[i]);
		} // Of for i
		System.out.println();
		
		DataNode[][] tempMatrix = new DataNode[2][length];
		
		// Step 2. Copy data.
		for (int i = 0; i < length; i++) {
			tempMatrix[0][i] = data[i];
		} // Of for i
		
		// Step 3. Merge. log n rounds
		tempRow = -1;
		for (int tempSize = 1; tempSize <= length; tempSize *= 2) {
			// Reuse the space of the two rows.
			tempRow++;
			System.out.println("Current row = " + tempRow);
			tempActualRow = tempRow % 2;
			tempNextRow = (tempRow + 1) % 2;
			
			tempGroups = length / (tempSize * 2);
			if (length % (tempSize * 2) != 0) {
				tempGroups++;
			} // Of if
			System.out.println("tempSize = " + tempSize + ", numGroups = " + tempGroups);
			
			for (tempGroupNumber = 0; tempGroupNumber < tempGroups; tempGroupNumber++) {
				tempFirstStart = tempGroupNumber * tempSize * 2;
				tempSecondStart = tempGroupNumber * tempSize * 2 + tempSize;
				if (tempSecondStart > length - 1) {
					// Copy the first part.
					for (int i = tempFirstStart; i < length; i++) {
						tempMatrix[tempNextRow][i] = tempMatrix[tempActualRow][i];
					} // Of for i
					continue;
				} // Of if
				tempSecondEnd = tempGroupNumber * tempSize * 2 + tempSize * 2 - 1;
				if (tempSecondEnd > length - 1) {
					tempSecondEnd = length - 1;
				} // Of if
				
				System.out
						.println("Trying to merge [" + tempFirstStart + ", " + (tempSecondStart - 1)
						+ "] with [" + tempSecondStart + ", " + tempSecondEnd + "]");
				tempFirstIndex = tempFirstStart;
				tempSecondIndex = tempSecondStart;
				tempNumCopied = 0;
				while ((tempFirstIndex <= tempSecondStart - 1)
						&& (tempSecondIndex <= tempSecondEnd)) {
					if (tempMatrix[tempActualRow][tempFirstIndex].key <= tempMatrix[tempActualRow][tempSecondIndex].key) {
						tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
						tempFirstIndex++;
						System.out.println("Copying " + tempMatrix[tempActualRow][tempFirstIndex]);
					} else {
						tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
						System.out.println("Copying " + tempMatrix[tempActualRow][tempSecondIndex]);
						tempSecondIndex++;
					} // Of if
					tempNumCopied++;
				} // Of while
				
				while (tempFirstIndex <= tempSecondStart - 1) {
					tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
					tempFirstIndex++;
					tempNumCopied++;
				} // Of while
				
				while (tempSecondIndex <= tempSecondEnd) {
					tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
					tempSecondIndex++;
					tempNumCopied++;
				} // Of while
			} // Of for groupNumber
			
			System.out.println("Round " + tempRow);
			for (int i = 0; i < length; i++) {
				System.out.println(tempMatrix[tempNextRow][i] + " ");
			} // Of for i
			System.out.println();
		} // Of for tempSize
		
		data = tempMatrix[tempNextRow];
		
	} // Of mergeSort
	
	/**
	 *******************
	 * Test the method.
	 *******************
	 */
	public static void mergeSortTest() {
		int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
		String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
		DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
		
		System.out.println(tempDataArray);
		
		tempDataArray.mergeSort();
		System.out.println("Result\r\n" + tempDataArray);
		
	} // Of mergeSortTest
	
	/**
	 *********************
	 * The entrance of the program.
	 * 
	 * @param args
	 *            Not used now.
	 *********************
	 */
	public static void main(String[] args) {
		System.out.println("\r\n-------------sequentialSearchTest-------------");
		sequentialSearchTest();
		
		System.out.println("\r\n-------------binarySearchTest-------------");
		binarySearchTest();
		
		System.out.println("\r\n-------------hashSearchTest-------------");
		hashSearchTest();
		
		System.out.println("\r\n-------------insertionSort-------------");
		insertionSortTest();
		
		System.out.println("\r\n-------------shellSort-------------");
		shellSortTest();
		
		System.out.println("\r\n-------------bubbleSort-------------");
		bubbleSortTest();
		
		System.out.println("\r\n-------------quickSort-------------");
		quickSortTest();
		
		System.out.println("\r\n-------------selectionSort-------------");
		selectionSortTest();
		
		System.out.println("\r\n-------------heapSort-------------");
		heapSortTest();
		
		System.out.println("\r\n-------------mergeSort-------------");
		mergeSortTest();
	} // Of main
	

截图:

举报

相关推荐

0 条评论