直接插入排序
希尔排序
活动地址:CSDN21天学习挑战赛
目录
1. 直接插入排序
1.1 定义
直接插入排序是一种最简单的排序方法,其基本操作是将一个记录插入到已排好的有序列表中,从而得到一个新的、记录数量增一的有序表
1.2 说明
直接插入排序的做法是:
每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。
1.3 代码示例
public static void insertSort(int[] array) {
for (int i = 1; i < array.length; i++) {
int tmp = array[i];
int j = i - 1;
for (; j >= 0; j--) {
if (array[j] > tmp) {
array[j+1] = array[j];
}else {
break;
}
}
array[j+1] = tmp;
}
}
1.4 复杂度
时间复杂度:
最好:O(n)
最坏:O(n^2)
平均:O(n^2)
空间复杂度:
O(1)
1.5 优缺点
优点:
具有稳定性
插入排序,初始数据越接近有序,时间效率越高
缺点:
比较次数不一定,比较次数少,插入点后的数据移动越多
2. 希尔排序
2.1 定义
希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。
2.2 说明
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。
**增量 gap 的范围: **1<= gap < 待排序数组的长度 (gap 需为 int 值)
**增量的取值: **一般的初次取序列(数组)的一半为增量,以后每次减半,直到增量为1。
第一个增量=数组的长度/2,
第二个增量= 第一个增量/2,
第三个增量=第二个增量/2,
以此类推,最后一个增量=1。
应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。
2.3 代码示例
public static void shell(int[] array, int gap) {
for (int i = gap; i < array.length; i++) {
int tmp = array[i];
int j = i - gap;
for (; j > 0; j -= gap) {
if (array[j] > tmp) {
array[j+gap] = array[j];
}else {
break;
}
}
array[j+gap] = tmp;
}
}
/**
* 希尔排序
* @param array [description]
*/
public static void shellSort(int[] array) {
int gap = array.length;
while (gap > 1) {
shell(array.gap);
gap /= 2;
}
shell(array,1);
}
2.4 复杂度
1)时间复杂度
O(n^1.3 - n^1.5)
希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比O(n²)好一些。
2)空间复杂度
O(1)
2.5 优缺点
优点:
比直接插入排序快,移动数据少
缺点:
不具有稳定性,并且分组不定