直接插入排序
直接插⼊排序是⼀种简单的插⼊排序法,其基本思想是:把待排序的记录按其关键码值的⼤⼩逐个插 ⼊到⼀个已经排好序的有序序列中,直到所有的记录插⼊完为⽌,得到⼀个新的有序序列。
例如:我们玩扑克牌时,就⽤了插⼊排序的思想
当插⼊第 i(i>=1) 个元素时,前⾯的 array[0],array[1],…,array[i-1] 已经排好序,此时 array[i] 的排序码与 即将 array[i-1],array[i-2],… 的排序码顺序进⾏⽐较,找到插⼊位置 array[i] 插⼊,原来位置上的元素顺序后移
例:将下面数字升序排列
首先,选择第一个元素10,此时只有一个元素,默认已排好序,当插入第二个元素9时,比较9与10,10>9,因此,10后移至第二个元素处,9插入第一个元素处,完成后如下图
我们令end为前面已排好序的序列中最后一个位置,tem为将要插入的元素
以上图为例,end为4,tem为5,设上图序列为数组a,a[end]>tem,则有a[end+1]==a[end],a[end]=tem,end--
继续上述操作直至end<0,tem元素插入完成
最后一次插入如下
代码实现如下
void DirectInsertSort(int* arr, int n)
{for (int i = 0; i < n - 1; i++){int end = i, tem = arr[end + 1]; while (end >= 0){if (arr[end] > tem){arr[end + 1] = arr[end];arr[end] = tem;}else{break; } //若不用交换,则直接进入下一次for循环end--;}}
}
直接插⼊排序时间复杂度为O(n^2)
降序排列为升序时,时间复杂度为O(n^2)
序列大致为升序时,时间复杂度将近为O(n)
直接插⼊排序的特性总结
1.元素集合越接近有序,直接插⼊排序算法的时间效率越⾼
2.时间复杂度:O(N^2)
3.空间复杂度:O(1)
希尔排序
希尔排序法⼜称缩⼩增量法。希尔排序法的基本思想是:先选定⼀个整数(通常是gap=n/3+1),把 待排序⽂件所有记录分成各组,所有的距离相等的记录分在同⼀组内,并对每⼀组内的记录进⾏排 序,然后gap=gap/3+1得到下⼀个整数,再将数组分成各组,进⾏插⼊排序,当gap=1时,就相当于 直接插⼊排序。 它是在直接插⼊排序算法的基础上进⾏改进⽽来的,综合来说它的效率肯定是要⾼于直接插⼊排序算 法的
因为end=end+/-gap,tem=a[end+gap],所以排序到最后时,end==n-gap
为什么gap=gap/3+1,因为
代码如下
void ShellSort(int* arr, int n)
{int gap = n;while (gap > 1){gap = gap / 3 + 1;for (int i = 0; i < n - gap; i++){int end = i, tem = arr[end + gap];while (end >= 0){if (arr[end] > tem){arr[end + gap] = arr[end];arr[end] = tem;}elsebreak;end-=gap;}}}
}
希 尔排序的特性总结
1. 希尔排序是对直接插⼊排序的优化。
2. 当 gap > 1 时都是预排序,⽬的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序的了,这样就会很快。这样整体⽽⾔,可以达到优化的效果
希尔排序时间复杂度不好计算,因为 gap 的取值很多,导致很难去计算,因此很多书中给出的希尔排 序的时间复杂度都不固定。《数据结构(C语⾔版)》---严蔚敏书中给出的时间复杂度为: