一、插入排序
1.1 插入排序的基本思想
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
在现实生活中的应用如:玩扑克牌时
1.2 插入排序的分析
当插入第i(i>=1)个元素时,前面的array[0],array[1],...,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],...的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。这里我们默认在end及end之前的元素已经排好序了。
1.3 插入排序的实现
c
//直接插入排序
//保证前n个数据有序
void InsertSort(int* arr, int n)
{
for(int i=0;i<n-1;i++)
{
int end=i;
//前n个有序的情况下对下一个排序
int temp = arr[end+1];
while (end >= 0)
{
if (arr[end] < arr[end+1])
{
swap(&arr[end], &arr[end+1]);
end--;
}
else
{
break;
}
}
arr[end+1] = temp;
}
}
1.4 插入排序的时间复杂度分析
二、希尔排序 ( 缩小增量排序 )
2.1 希尔排序的基本思想
- 逆序有序的数组排序时,时间复杂度为 O(n^2)),此时效率最低。
- 顺序有序的数组排序时,时间复杂度为O ( n ),此时效率最高
我们发现,当被排序的对象越接近有序时,插入排序的效率越高,那我们是否有办法将数组变成接近有序后再用插入排序,此时希尔大佬就发现了这个排序算法,并命名为希尔排序。
2.2 希尔排序的分析
希尔排序是对插入排序的优化,基本思路是先选定一个整数作为增量,把待排序文件中的所有数据分组,以每个距离的等差数列为一组,对每一组进行排序,然后将增量缩小,继续分组排序,重复上述动作,直到增量缩小为1时,排序完正好有序。
希尔排序原理是每一对分组进行排序后,整个数据就会更接近有序,当增量缩小为1时,就是插入排序,但是现在的数组非常接近有序,移动的数据很少,所以效率非常高,所以希尔排序又叫缩小增量排序。
每次排序让数组接近有序的过程叫做预排序
c
//希尔排序
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;
int temp = arr[end + gap];
while (end >= 0)
{
if (arr[end] < arr[end + gap])
{
swap(&arr[end], &arr[end + gap]);
end-=gap;
}
else
{
break;
}
}
arr[end + gap] = temp;
}
}
}