直接插入排序(插入排序)-八大排序汇总(4)

基本思想

  直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。

  直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。

时间复杂度

  O(n^2)

空间复杂度

  O(1)

稳定性

  如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

代码

严格按定义书写的代码

 1 void Insertsort1(int a[], int n)
 2 {
 3     int i, j, k;
 4     for (i = 1; i < n; i++)
 5     {
 6         //为a[i]在前面的a[0...i-1]有序区间中找一个合适的位置
 7         for (j = i - 1; j >= 0; j--)
 8             if (a[j] <= a[i]) //注意插入排序是稳定的,所以a[j]=a[i]时也不处理
 9                 break;
10 
11         //如找到了一个合适的位置
12         if (j != i - 1)
13         {
14             //将比a[i]大的数据向后移
15             int temp = a[i];
16             for (k = i - 1; k > j; k--)
17                 a[k + 1] = a[k];
18             //将a[i]放到正确位置上
19             a[k + 1] = temp;
20         }
21     }
22 }

  将上面代码进行简化,将搜索和数据后移这二个步骤合并。

 1 void Insertsort2(int a[], int n)
 2 {
 3     int i, j;
 4     for (i = 1; i < n; i++)
 5     {
 6         int temp = a[i];
 7         for (j = i - 1; j >= 0 && a[j] > temp; j--)
 8             a[j + 1] = a[j];
 9         a[j + 1] = temp;
10     }
11     print(a, 10);
12 }

  在某些极端的情况下,对内存需要特别严格时,比如不用temp变量(去掉哨兵)完成直接插入排序,又该如何实现呢。

 1 inline void Swap(int &a, int &b)
 2 {
 3     if (a != b)
 4     {
 5         a ^= b;
 6         b ^= a;
 7         a ^= b;
 8     }
 9 }
10 void Insertsort3(int a[], int n)
11 {
12     int i, j;
13     for (i = 1; i < n; i++)
14         for (j = i - 1; j >= 0 && a[j] > a[j + 1]; j--)
15             Swap(a[j], a[j + 1]);
16 }

 

posted on 2015-10-04 14:56  306573704  阅读(418)  评论(0编辑  收藏  举报

导航