50.1 比较分析各种查找算法
顺序查找:时间复杂度:O(n);可用于有序或无序数据;按顺序查找元素。
折半查找:时间复杂度:O(logn);只能用于有序数据;从中间元素开始查找,每次比较会将查找范围缩小一半。
哈希查找:时间复杂度O(1),用空间换时间;需要先通过相应的散列函数和解决冲突的办法创建哈希表,再通过键值定位要查找的元素。
50.2 设计一个自己的 Hash 函数和一个冲突解决机制
/**
******************
* The second constructor. For Hash code only.It is assumed that paraKeyArray.
* length <= paraLength.
*
* @param paraKeyArray The array of the keys.
* @param paraContentArray The array of contents.
* @param paraLength The space for the Hash table.
******************
*/
public DataArray(int[] paraKeyArray, String[] paraContentArray, int paraLength) {
// Step 1. Initialize.
length = paraLength;
data = new DataNode[length];
for (int i = 0; i < length; i++) {
data[i] = null;
} // Of for i
// Step 2. Fill the data.
int tempPosition;
for (int i = 0; i < paraKeyArray.length; i++) {
// Hash.
tempPosition = (paraKeyArray[i] * paraKeyArray[i]) % paraLength;
// Find and empty position
int k = 1;
while (data[tempPosition] != null) {
tempPosition = (tempPosition + k) % paraLength;
System.out.println("Collision, move forward for key " + paraKeyArray[i]);
if (k % 2 == 0) {
k++;
k = -k;
} else {
k = -k;
k++;
}
} // Of while
data[tempPosition] = new DataNode(paraKeyArray[i], paraContentArray[i]);
} // Of for i
}// Of the second constructor
/**
*********************
* Hash search.
*
* @param paraKey The given key.
* @return The content of the key.
*********************
*/
public String hashSearch(int paraKey) {
int tempPosition = (paraKey * paraKey) % length;
int k = 1;
while (data[tempPosition] != null) {
if (data[tempPosition].key == paraKey) {
return data[tempPosition].content;
} // Of if
System.out.println("Not this one for " + paraKey);
tempPosition = (tempPosition + k) % length;
if (k % 2 == 0) {
k++;
k = -k;
} else {
k = -k;
k++;
}
} // Of while
return "null";
}// Of hashSearch
/**
*********************
* Test the method.
*********************
*/
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));
}// Of hashSearchTest
Hash函数(平方除留余数法):
tempPosition = (paraKeyArray[i] * paraKeyArray[i]) % paraLength;
冲突解决机制:
d=1, -2, 3, -4......;当冲突发生时则反向查看下一个元素。
结果:
50.3 比较分析各种排序算法
时间复杂度 | 空间复杂度 | 是否稳定 | |
插入排序 | O(n^2) | O(1) | 是 |
希尔排序 | O(n^2) | O(1) | 否 |
冒泡排序 | O(n^2) | O(1) | 是 |
快速排序 | O(nlogn) | O(nlogn) | 否 |
选择排序 | O(n^2) | O(1) | 否 |
堆排序 | O(nlogn) | O(1) | 否 |
归并排序 | O(nlogn) | O(n) | 是 |
50.4 描述各种排序算法的特点和基本思想
插入排序:将待排序元素插入到有序的子序列中。
希尔排序: ①通过增量将序列分成若干子序列,②将若干子序列进行插入排序,再通过减小增量循环①②步直至增量为1即排好序。
冒泡排序:比较相邻两元素的大小,一次排序可定一个元素最终位置,当元素不再交换时则已排好序。
快速排序:基于分治思想,选择基准元素通过一趟排序将序列分成独立两部分,再进行选择、划分直至只有一个元素。
选择排序:在未排好序的序列中找出最小或者最大值,将其与第一个或最后一个元素交换,n-1趟后即可获得排好的序列。
堆排序:将序列构造成一颗大根堆(小根堆),每次输出堆顶元素再重新调整成大根堆(小根堆)循环至只剩一个元素。
归并排序:将两个有序的序列归并成一个有序的序列,直至形成最终序列。