Java学习日记(41-50天,查找与排序)

2 篇文章 0 订阅
1 篇文章 0 订阅

学习地址

第 41 天: 顺序查找与折半查找

顺序查找:

设置第一个位置data[0]的值为哨兵,从后往前遍历,如果一直遍历到哨兵的位置说明未找到该元素。
顺序查找时间复杂度为 O(n).

二分查找:

前提是一个有序序列,设置一个左指针left,初始值为最左边下标,右指针right,初始值为最右边下标。计算mid=(left+right)/2;如果data[mid].key等于要查找的值则返回,如果data[mid].key大于查找值,说明要查找的值在左侧,修改右指针,right=mid-1;如果data[mid].key小于查找值,说明要查找的值在右边,修改左指针,left=mid+1.
二分查找的时间复杂度为O(log n)。

代码:

package xjx;

public class DataArray {

	class DataNode {
		
		int key;

		String content;

		DataNode(int paraKey, String paraContent) {
			key = paraKey;
			content = paraContent;
		}

		public String toString() {
			return "(" + key + ", " + content + ") ";
		}
	}

	DataNode[] data;

	int length;

	public DataArray(int[] paraKeyArray, String[] paraContentArray) {
		length = paraKeyArray.length;
		data = new DataNode[length];

		for (int i = 0; i < length; i++) {
			data[i] = new DataNode(paraKeyArray[i], paraContentArray[i]);
		}
	}

	public String toString() {
		String resultString = "I am a data array with " + length + " items.\r\n";
		for (int i = 0; i < length; i++) {
			resultString += data[i] + " ";
		}

		return resultString;
	}

	public String sequentialSearch(int paraKey) {
		data[0].key = paraKey;

		int i;
		//由于数据[0].key=paraKey,所以我们不判断i>=0。
		//这样运行时节省了大约1/2。
		for (i = length - 1; data[i].key != paraKey; i--)
			;

		return data[i].content;
	}

	public static void sequentialSearchTest() {
		int[] tempUnsortedKeys = { -1, 5, 3, 6, 10, 7, 1, 9 };
		String[] tempContents = { "null", "if", "then", "else", "switch", "case", "for", "while" };
		DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

		System.out.println(tempDataArray);

		System.out.println("Search result of 10 is: " + tempDataArray.sequentialSearch(10));
		System.out.println("Search result of 5 is: " + tempDataArray.sequentialSearch(5));
		System.out.println("Search result of 4 is: " + tempDataArray.sequentialSearch(4));
	}

	public String binarySearch(int paraKey) {
		int tempLeft = 0;
		int tempRight = length - 1;
		int tempMiddle = (tempLeft + tempRight) / 2;

		while (tempLeft <= tempRight) {
			tempMiddle = (tempLeft + tempRight) / 2;
			if (data[tempMiddle].key == paraKey) {
				return data[tempMiddle].content;
			} else if (data[tempMiddle].key <= paraKey) {
				tempLeft = tempMiddle + 1;
			} else {
				tempRight = tempMiddle - 1;
			}
		}
		//找不到
		return "null";
	}

	public static void binarySearchTest() {
		int[] tempSortedKeys = { 1, 3, 5, 6, 7, 9, 10 };
		String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
		DataArray tempDataArray = new DataArray(tempSortedKeys, tempContents);

		System.out.println(tempDataArray);

		System.out.println("Search result of 10 is: " + tempDataArray.binarySearch(10));
		System.out.println("Search result of 5 is: " + tempDataArray.binarySearch(5));
		System.out.println("Search result of 4 is: " + tempDataArray.binarySearch(4));
	}

	public static void main(String args[]) {
		System.out.println("\r\n-------sequentialSearchTest-------");
		sequentialSearchTest();

		System.out.println("\r\n-------binarySearchTest-------");
		binarySearchTest();
	}
}

查找结果:
在这里插入图片描述

第 42 天: 哈希表

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

1.使用 (最简单的) 除数取余法获得数据存放地址 (下标).
2.使用 (最简单的) 顺移位置法解决冲突.
3.搜索的时间复杂度仅与冲突概率相关, 间接地就与装填因子相关. 如果空间很多, 可以看出时间复杂度为O(1).

public DataArray(int[] paraKeyArray, String[] paraContentArray, int paraLength) {
	// 初始化
	length = paraLength;
	data = new DataNode[length];

	for (int i = 0; i < length; i++) {
		data[i] = null;
	}

	// 填数据
	int tempPosition;

	for (int i = 0; i < paraKeyArray.length; i++) {
		// 哈希
		tempPosition = paraKeyArray[i] % paraLength;

		// 找到一个空位置
		while (data[tempPosition] != null) {
			tempPosition = (tempPosition + 1) % paraLength;
			System.out.println("Collision, move forward for key " + paraKeyArray[i]);
		}

		data[tempPosition] = new DataNode(paraKeyArray[i], paraContentArray[i]);
	}
}

public String hashSearch(int paraKey) {
	int tempPosition = paraKey % length;
	while (data[tempPosition] != null) {
		if (data[tempPosition].key == paraKey) {
			return data[tempPosition].content;
		}
		System.out.println("Not this one for " + paraKey);
		tempPosition = (tempPosition + 1) % length;
	}

	return "null";
}

public static void hashSearchTest() {
	int[] tempUnsortedKeys = { 16, 33, 38, 69, 57, 95, 86 };
	String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
	DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents, 19);

	System.out.println(tempDataArray);

	System.out.println("Search result of 95 is: " + tempDataArray.hashSearch(95));
	System.out.println("Search result of 38 is: " + tempDataArray.hashSearch(38));
	System.out.println("Search result of 57 is: " + tempDataArray.hashSearch(57));
	System.out.println("Search result of 4 is: " + tempDataArray.hashSearch(4));
}

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();
}

哈希表的插入与查找结果:
哈希表

第 43 天: 插入排序

插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。
插入排序是一种最简单的排序方法,它的基本思想是将一个元素插入到已经排好序的有序表中,从而形成一个新的、元素数加1的有序表。
在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动 。
代码:

public void insertionSort() {
	DataNode tempNode;
	int j;
	for (int i = 2; i < length; i++) {
		tempNode = data[i];
		
		//找到插入的位置并移动后面的元素
		for (j = i - 1; data[j].key > tempNode.key; j--) {
			data[j + 1] = data[j];
		}
		
		//插入
		data[j + 1] = tempNode;
		
		System.out.println("Round " + (i - 1));
		System.out.println(this);
	}
}

public static void insertionSortTest() {
	int[] tempUnsortedKeys = { -100, 5, 3, 6, 10, 7, 1, 9 };
	String[] tempContents = { "null", "if", "then", "else", "switch", "case", "for", "while" };
	DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

	System.out.println(tempDataArray);

	tempDataArray.insertionSort();
	System.out.println("Result\r\n" + tempDataArray);
}

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-------insertionSortTest-------");
	insertionSortTest();
}

插入排序结果:
在这里插入图片描述

第 44 天: 希尔排序

希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。

图解:这里是引用

public void shellSort() {
	DataNode tempNode;
	int[] tempJumpArray = { 5, 3, 1 };
	int tempJump;
	int p;
	for (int i = 0; i < tempJumpArray.length; i++) {
		tempJump = tempJumpArray[i];
		for (int j = 0; j < tempJump; j++) {
			for (int k = j + tempJump; k < length; k += tempJump) {
				tempNode = data[k];
				// 找到插入位置,并移动元素
				for (p = k - tempJump; p >= 0; p -= tempJump) {
					if (data[p].key > tempNode.key) {
						data[p + tempJump] = data[p];
					} else {
						break;
					}
				}

				//插入
				data[p + tempJump] = tempNode;
			}
		}
		System.out.println("Round " + i);
		System.out.println(this);
	}
}

public static void shellSortTest() {
	int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9, 12, 8, 4 };
	String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while", "throw", "until", "do" };
	DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

	System.out.println(tempDataArray);

	tempDataArray.shellSort();
	System.out.println("Result\r\n" + tempDataArray);
}

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-------insertionSortTest-------");
	insertionSortTest();
	
	System.out.println("\r\n-------shellSortTest-------");
	shellSortTest();
}

希尔排序结果:
在这里插入图片描述

第 45 天: 冒泡排序

双重循环,只交换相邻位置,每次确定当前无序中的最大值,也就是每趟排序可以确定一个元素的最终位置,如果某一趟没有交换,表示已经排好序,结束循环。

代码:
其中tempNode需要初始化NULL,不然会报错。

public void bubbleSort() {
	boolean tempSwapped;
	DataNode tempNode = null;
	for (int i = length - 1; i > 1; i--) {
		tempSwapped = false;
		for (int j = 0; j < i; j++) {
			if (data[j].key > data[j + 1].key) {
				//交换
				tempNode = data[j + 1];
				data[j + 1] = data[j];
				data[j] = tempNode;

				tempSwapped = true;
			}
		}

		//如果本趟循环没有交换,则说明已经有序
		if (!tempSwapped) {
			System.out.println("Premature");
			break;
		}

		System.out.println("Round " + (length - i));
		System.out.println(this);
	}
}

public static void bubbleSortTest() {
	int[] tempUnsortedKeys = { 1, 3, 6, 10, 7, 5, 9 };
	String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
	DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

	System.out.println(tempDataArray);

	tempDataArray.bubbleSort();
	System.out.println("Result\r\n" + tempDataArray);
}

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-------insertionSortTest-------");
	insertionSortTest();
	
	System.out.println("\r\n-------shellSortTest-------");
	shellSortTest();
	
	System.out.println("\r\n-------bubbleSortTest-------");
	bubbleSortTest();
}

冒泡排序结果:
在这里插入图片描述

第 46 天: 快速排序

快速排序,就是给基准数据找其正确索引位置的过程。

①先从队尾开始向前扫描且当low < high时,如果a[high] > tmp,则high–,但如果a[high] <tmp,则将high的值赋值给low,即arr[low] = a[high],同时要转换数组扫描的方式,即需要从队首开始向队尾进行扫描了。
②同理,当从队首开始向队尾进行扫描时,如果a[low] < tmp,则low++,但如果a[low] >tmp了,则就需要将low位置的值赋值给high位置,即arr[low] =arr[high],同时将数组扫描方式换为由队尾向队首进行扫描。
③不断重复①和②,知道low>=high时(其实是low=high),low或high的位置就是该基准数据在数组中的正确索引位置。

快速排序的平均时间复杂度为O(nlgn),当序列基本有序时时间复杂度最坏,为O(n2).

public void quickSortRecursive(int paraStart, int paraEnd) {
	//快排结束
	if (paraStart >= paraEnd) {
		return;
	}

	int tempPivot = data[paraEnd].key;
	DataNode tempNodeForSwap;

	int tempLeft = paraStart;
	int tempRight = paraEnd - 1;

	//找到枢轴的位置,同时将较小的元素向左移动,将较大的元素向右移动
	while (true) {
		while ((data[tempLeft].key < tempPivot) && (tempLeft < tempRight)) {
			tempLeft++;
		}

		while ((data[tempRight].key > tempPivot) && (tempLeft < tempRight)) {
			tempRight--;
		}

		if (tempLeft < tempRight) {
			//交换
			System.out.println("Swapping " + tempLeft + " and " + tempRight);
			tempNodeForSwap = data[tempLeft];
			data[tempLeft] = data[tempRight];
			data[tempRight] = tempNodeForSwap;
		} else {
			break;
		}
	}

	//交换
	if (data[tempLeft].key > tempPivot) {
		tempNodeForSwap = data[paraEnd];
		data[paraEnd] = data[tempLeft];
		data[tempLeft] = tempNodeForSwap;
	} else {
		tempLeft++;
	}

	System.out.print("From " + paraStart + " to " + paraEnd + ": ");
	System.out.println(this);

	quickSortRecursive(paraStart, tempLeft - 1);
	quickSortRecursive(tempLeft + 1, paraEnd);
}

public void quickSort() {
	quickSortRecursive(0, length - 1);
}

public static void quickSortTest() {
	int[] tempUnsortedKeys = { 1, 3, 12, 10, 5, 7, 9 };
	String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
	DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

	System.out.println(tempDataArray);

	tempDataArray.quickSort();
	System.out.println("Result\r\n" + tempDataArray);
}

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-------insertionSortTest-------");
	insertionSortTest();
	
	System.out.println("\r\n-------shellSortTest-------");
	shellSortTest();
	
	System.out.println("\r\n-------bubbleSortTest-------");
	bubbleSortTest();
	
	System.out.println("\r\n-------quickSortTest-------");
	quickSortTest();
}

快排结果:
在这里插入图片描述

第 47 天: 选择排序

选择排序(Selection sort)是一种简单直观的排序算法。
它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
每趟排序可以确定一个元素的位置。
时间复杂度为O(n)

public void selectionSort() {
	DataNode tempNode;
	int tempIndexForSmallest;

	for (int i = 0; i < length - 1; i++) {
		//初始化
		tempNode = data[i];
		tempIndexForSmallest = i;
		for (int j = i + 1; j < length; j++) {
			if (data[j].key < tempNode.key) {
				tempNode = data[j];
				tempIndexForSmallest = j;
			}
		}

		//更改当前元素
		data[tempIndexForSmallest] = data[i];
		data[i] = tempNode;
	}
}

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);
}

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-------insertionSortTest-------");
	insertionSortTest();
	
	System.out.println("\r\n-------shellSortTest-------");
	shellSortTest();
	
	System.out.println("\r\n-------bubbleSortTest-------");
	bubbleSortTest();
	
	System.out.println("\r\n-------quickSortTest-------");
	quickSortTest();
	
	System.out.println("\r\n-------selectionSortTest-------");
	selectionSortTest();
}

选择排序结果:
在这里插入图片描述

第 48 天: 堆排序

堆排序是利用堆(二叉树)这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。

步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。
步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。最后生成一个有序的堆。

public void heapSort() {
	DataNode tempNode;
	//建立初试堆
	for (int i = length / 2 - 1; i >= 0; i--) {
		adjustHeap(i, length);
	}
	System.out.println("The initial heap: " + this + "\r\n");

	//交换和重建堆
	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);
	}
}

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) {
		//右孩子更大
		if (tempChild + 1 < paraLength) {
			if (data[tempChild].key < data[tempChild + 1].key) {
				tempChild++;
			}
		}

		System.out.println("The parent position is " + tempParent + " and the child is " + tempChild);
		if (tempKey < data[tempChild].key) {
			//更大的孩子交换
			data[tempParent] = data[tempChild];
			System.out.println("Move " + data[tempChild].key + " to position " + tempParent);
			tempParent = tempChild;
		} else {
			break;
		}
	}

	data[tempParent] = tempNode;

	System.out.println("Adjust " + paraStart + " to " + paraLength + ": " + this);
}

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);
}

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-------insertionSortTest-------");
	insertionSortTest();
	
	System.out.println("\r\n-------shellSortTest-------");
	shellSortTest();
	
	System.out.println("\r\n-------bubbleSortTest-------");
	bubbleSortTest();
	
	System.out.println("\r\n-------quickSortTest-------");
	quickSortTest();
	
	System.out.println("\r\n-------selectionSortTest-------");
	selectionSortTest();
	
	System.out.println("\r\n-------heapSortTest-------");
	heapSortTest();
}

堆排序结果:
在这里插入图片描述
在这里插入图片描述

第 49 天: 归并排序

归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并排序进行 log n 轮循环,每轮O(n) 次拷贝,因此时间复杂度为 O(nlog ⁡n)。

public void mergeSort() {
	int tempRow; // 现在的Row
	int tempGroups; // 数组个数
	int tempActualRow; // 只有0和1
	int tempNextRow = 0;
	int tempGroupNumber;
	int tempFirstStart, tempSecondStart, tempSecondEnd;
	int tempFirstIndex, tempSecondIndex;
	int tempNumCopied;
	for (int i = 0; i < length; i++) {
		System.out.print(data[i]);
	}
	System.out.println();

	DataNode[][] tempMatrix = new DataNode[2][length];

	//赋值
	for (int i = 0; i < length; i++) {
		tempMatrix[0][i] = data[i];
	}

	//logn次循环
	tempRow = -1;
	for (int tempSize = 1; tempSize <= length; tempSize *= 2) {
		// 重新利用
		tempRow++;
		System.out.println("Current row = " + tempRow);
		tempActualRow = tempRow % 2;
		tempNextRow = (tempRow + 1) % 2;

		tempGroups = length / (tempSize * 2);
		if (length % (tempSize * 2) != 0) {
			tempGroups++;
		}
		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) {
				//复制第一部分
				for (int i = tempFirstStart; i < length; i++) {
					tempMatrix[tempNextRow][i] = tempMatrix[tempActualRow][i];
				}
				continue;
			}
			tempSecondEnd = tempGroupNumber * tempSize * 2 + tempSize * 2 - 1;
			if (tempSecondEnd > length - 1) {
				tempSecondEnd = length - 1;
			}

			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++;
				}
				tempNumCopied++;
			}

			while (tempFirstIndex <= tempSecondStart - 1) {
				tempMatrix[tempNextRow][tempFirstStart
						+ tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
				tempFirstIndex++;
				tempNumCopied++;
			}

			while (tempSecondIndex <= tempSecondEnd) {
				tempMatrix[tempNextRow][tempFirstStart
						+ tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
				tempSecondIndex++;
				tempNumCopied++;
			}
		}

		System.out.println("Round " + tempRow);
		for (int i = 0; i < length; i++) {
			System.out.print(tempMatrix[tempNextRow][i] + " ");
		}
		System.out.println();
	}

	data = tempMatrix[tempNextRow];
}

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(tempDataArray);
}

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-------insertionSortTest-------");
	insertionSortTest();
	
	System.out.println("\r\n-------shellSortTest-------");
	shellSortTest();
	
	System.out.println("\r\n-------bubbleSortTest-------");
	bubbleSortTest();
	
	System.out.println("\r\n-------quickSortTest-------");
	quickSortTest();
	
	System.out.println("\r\n-------selectionSortTest-------");
	selectionSortTest();
	
	System.out.println("\r\n-------heapSortTest-------");
	heapSortTest();
	
	System.out.println("\r\n-------mergeSortTest-------");
	mergeSortTest();
}

归并排序结果:
在这里插入图片描述
在这里插入图片描述

第 50 天: 小结

比较分析各种查找算法.

  1. 顺序查找
    顺序查找,按照字面意思,就是按照排列顺序,依次将查找关键词key与元数据每一项进行对比,如果找到就结束。 适用所有数据,但是对于过大的数据,不太实用,时间复杂度较高 ,时间复杂度O(n),空间复杂度O(1)
    2.折半查找
    假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
    适用范围数据有序,时间复杂度O(log n),空间复杂度O(1)
    3.哈希表查找
    根据键值方式(Key value)进行查找,通过散列函数,定位数据元素。首先需要建立hash表。时间复杂度在不冲突的情况下O(1),最极端情况为O(n),空间复杂度O(1)

设计一个自己的 Hash 函数和一个冲突解决机制.

根据哈希表长度,每次求余哈希表的长度,得到的值就作为存放位置,当遇到相同的,就依此顺移

比较分析各种排序算法并描述各种排序算法的特点和基本思想…

直接插入排序:
每次取一个记录插入到已经排好序的有序表中,得到一个新的有序表。在插入过程中为了防止下标出界,需要在r[0]处加入一个监视哨。该算法的时间复杂度为O(n2),双层嵌套循环;空间复杂度为O(1),因为只需要一个额外的空间存储监视哨。
希尔排序:
希尔排序是由直接插入排序发展而来,将待排序列分割成若干个子序列,并分别进行直接插入排序,(子序列是由相隔某个增量的记录组成的,而非分段),最后进行一次直接插入排序。注意:增量序列的值应该没有除1以外的公因子,且最后一个增量值必须为1.该算法的时间复杂度小于O(n2),与选取的增量值相关。
冒泡排序:
每一轮排序都从第一位开始将相邻的两位进行比较,如果t-1位比t位的值大,则将其交换顺序。每轮排序后,都会将未排序序列的最大数移到最后一位。当开始时序列即为从小到大有序序列,只需要一次就可以完成排序,时间复杂度为O(n); 当序列为逆序排列时,所需排序次数为n-1次,每次比较的次数为n-i次,时间复杂度为O(n2);算法的平均时间复杂度为O(n2)
快速排序:
第一趟快排将列表分为两部分,一部分的关键字均比另一部分关键字小,然后再分别对两部分进行排序。算法首先选定一点作为枢纽,然后分别设置两个指针low和high,high从尾部开始,找到小于枢纽的点,将其与枢纽交换;然后low从头部开始找到大于枢纽的点将其与枢纽交换。依次排序后以枢纽为中心分为两部分,且左边均比枢纽小,右边均比枢纽大。快速排序的平均时间复杂度为所有内部排序中最优的,但是在序列有序的情况下,其性能不能达到O(n)。空间复杂度为O(logn),因为每次快排包括递归过程中的枢纽值,都需要存储在一个栈中。
归并排序:
是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序进行 log n 轮循环,每轮O(n) 次拷贝,因此时间复杂度为 O(nlog ⁡n)。
堆排序:
堆排序是利用堆(二叉树)这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值