文章目录
- 说明
- day43 插入排序
- 思路
- 代码
- day44 希尔排序
- 思路
- 代码
- 对比
说明
闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata
day43 插入排序
思路
插入排序基本思想:把一个待排序的数据插入到已经排序好的序列中。具体的步骤为:
- 1.将序列的第一个元素作为已经排序好的,其他元素看作未排序的;
- 2.遍历未排序的元素,将每一个元素都插入到已排序的序列中合适的位置,保证每一次插入后任然是有序的(直到遍历完所有的序列)
代码
插入排序的代码中第一个位置即data[0]的数据是没有用到的,赋值了一个很小的数据我们可以不用担心数据越界。
/**
* insertion sort.
* data[0] dose not store a valid data. data[0].key should be smaller than any valid key
*/
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);
}
day44 希尔排序
思路
希尔排序可以将他理解为插入排序的一种改进方法,基本思想是:将待排序的序列分为若干子序列,分别对每个子序列进行插入排序,在整个序列基本有序时,又进行一次整体的排序(这时的步长为1,这不就和我们插入排序一样了,但是这时的待排序数组变得基本有序,速度自然更快)(如下图模拟的希尔排序)
代码
在希尔排序的四次循环,最外的循环是循环要进行几趟排序,第二个循环是在这一趟排序中,有多少组子序列需要排序,在里面的双层循环就和插入排序一样了,找到合适的位置移动数据,再插入数据。在排序过程中,由于变量太多,所以数组位置的赋值很容易乱,需要理清思路,我在这个过程中就出错了。
/**
* shell sort.we do not use sentries here because too many of them are needed
*/
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];
// find the position to insert. at the same time, move other nodes
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);
}
对比
- 通过代码对比,插入排序:数据插入已经排好的序列,需要找到合适的插入位置,并移动数据,最后再插入数据。而希尔排序代码实现和插入排序实现很相似,插入排序只需要进行一次排序就好,而希尔排序要进行多次插入排序,而每一次排序有多个分组需要分别进行插入排序。
- 插入排序时间复杂度是O(n^2),在最坏的情况是数据全都逆序,最好的情况就是待排序数据基本有序;所以希尔排序更像是插入排序的改进版本,经过几次分组进行排序后数组也就基本变得有序了。
希尔排序的时间复杂度没有一个具体的值,因为分组的方式不同对时间复杂度的影响就不一样,若步长为1则就可以退化为插入排序,所以最差的时候时间复杂度可以达到 O(n^2)