排序之插入排序

1、直接插入排序是一种最简单的排序方法,它的基本操作是将一个记录插入到已排好序的有序表中,从而得到一个新的、记录增1的有序表。一般情况下,第i趟直接插入排序的操作为:在含有i-1个记录的有序

子列中插入一个记录r[i],变成含有i个记录的有序子序列。从已经排好序的部分的尾部向前找合适的位置插入。每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。

第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。

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

  直接插入排序是稳定的,算法复杂度为O(n^2).

 1 void InsertSort(int a[],int len)
 2 {
 3     int i, j;
 4     for ( i = 1; i < len; i++)
 5     {
 6         if (a[i] < a[i - 1])
 7         {
        //a[i]的值会被覆盖,所以先将其保存下来
8 int temp = a[i]; 9 for ( j = i - 1; j >= 0 && a[j] > temp; j--) 10 a[j+1] = a[j];//后移 11 a[j + 1] = temp; 12 } 13 } 14 }

2、折半插入排序:由于插入排序是在一个有序表中进行查找和插入,这个查找操作可以利用折半查找来实现,由此进行的插入排序称之为折半插入排序。

 1 void BInsertSort(Record *arr, int length) // length是要排序的元素的个数,0号单元除外
 2 {
 3 for (int i = 2; i <= length; ++i) {
 4 arr[0] = arr[i]; // 将arr[i]暂存到arr[0]
 5 int low = 1;
 6 int high = i - 1;
 7 while (low <= high) { // 在arr[low..high]中折半查找有序插入的位置
 8 int m = (low + high) / 2; // 折半
 9 if (arr[0].key < arr[m].key) // 关键字相同时,使low = m + 1,到高半区,保证稳定性
10 high = m - 1; // 插入点在低半区
11 else
12 low = m + 1; // 插入点在高半区
13 }
14 for (int j = i - 1; j >= high + 1; --j)
15 arr[j + 1] = arr[j]; // 记录后移
16 arr[high + 1] = arr[0]; // 插入
17 }
18 }

3、希尔排序又称“缩小增量排序”,它也属于一种插入排序类的方法。希尔排序是非稳定排序算法(快些“希”选一堆,是不稳定的)。基本思想:先将整个记录序列分割成若干个子序列分别插入排序,待整个序列中的记录“基本有序”时,再对

全体记录进行一次直接插入排序。子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。因此关键字记录不是一步一步地往前挪动,而是跳跃式的往前移,从而使得在进行最后一趟增量为1的插入排序时,序列已经基本有序。

 1 #include<iostream>
 2 using namespace std;
 3 //希尔排序。以gap为间距来分组数据,gap每一趟变为前一次的一半,直到最后一次gap=1
 4 //希尔排序实际也是插入排序,对每个子序列都进行插入排序,直到最后gap=1只有一个相对有序的子序列
 5 void ShellSort(int a[], int size)
 6 {
 7     int gap, i, j, temp;
 8     for (gap = size / 2; gap > 0; gap /= 2)
 9     {
10         //下面其实就是一个插入排序,对每个子序列进行插入排序
11         for (i = gap; i < size; i++)
12         {
13             if(a[i]<a[i-gap])
14             {
15                 int temp = a[i];//必须要保存,因为该位置会被前一个数覆盖
16                 for (j = i - gap; j >= 0 && a[j] >temp; j-=gap)//此处比较必须使用temp。因为a[i]值已经变了
17                     a[j + gap] = a[j];
18                 a[j + gap] = temp;
19             }
20         }
21     }
22 }
23 int main()
24 {
25     int a[]={9, 6, 3, 4, 5, 7};
26     ShellSort(a,6);
27     for (int i = 0; i < 6; i++)
28         cout << a[i] << endl;
29     return 0;
30 }

 

posted on 2017-10-10 20:59  wsw_seu  阅读(246)  评论(0编辑  收藏  举报

导航