【排序】插入排序

来源:互联网 发布:问卷调查表数据库设计 编辑:程序博客网 时间:2024/06/01 19:33

一、直接插入排序:

1.基本思想:

依次将每个记录插入到一个有序的子序列中去,插入后该记录序列仍是有序的。


2.具体做法:

先将待排序的记录序列中的第一个记录看成是一个有序子序列,然后从第二个记录起逐个进行插入,直至整个记录序列变成按关键字非递减有序的序列为止。


3.举例:

初始关键字: 8     3     2     5     9    4    6

           i=1 : [ 8 ] 3   2      5    9     4    6

           i=2 : [ 3   8 ]  2      5     9    4    6

           i=3 : [ 2   3    8 ]    5     9    4    6

           i=4 : [ 2   3    5     8 ]    9    4    6

           i=5 : [ 2   3    5     8     9 ]    4    6

           i=6 : [ 2   3    4    5      8     9 ]     6

   排序结果: [ 2    3    4    5     6      8      9 ]


4.算法:

public void InsertSort(int a[], int n)/* 用直接插入排序法对a[0]~a[n-1] 排序 */{int i, j;int temp;for (i = 1; i < n; i++) {temp = a[i]; /* 将要插入的记录暂存到temp 中 */j = i - 1; /* 从有序子序列的最高位开始比较 */while (j >= 0 && temp < a[j]) {a[j + 1] = a[j]; /* 将关键字>temp的记录后移 */j--;}a[j + 1] = temp; /* 插入到正确位置 */}}


5.算法分析
辅助空间:O(1)
时间:
(1)关键字的比较次数
最好(“ 正序” ): n-1

最坏(“ 逆序“): n(n-1) / 2

(2 )记录的移动次数
开始时,将要插入的记录→temp ,移动1,最后,将记录插入适当位置,即 temp →a[j+1]  ,移动1次。比较后,若temp.key<a[j].key ,则 a[j] →a[j+1]

最小移动量(“正序”时):2(n-1)

最大移动量(“逆序”时):(n-1)(n+4)/ 2

∴ 直接插入排序的 时间复杂度 为O(n^2)


二、折半插入排序

1.基本思想:

先将待排序的记录序列中的第一个记录看成是一个有序子序列,然后从第二个记录起依次将每个记录插入到一个有序的子序列中去,插入后该序列仍是有序的。但在查找插入位置时,不是采用顺序查找,而是采用折半查找。


2.算法:

public void BInsertSort(int a[], int n)/* 用折半插入排序法对a[0]~a[n-1] 排序 */{int i, j, low, high, mid;int temp;for (i = 1; i < n; i++) {temp = a[i]; /* 将要插入的记录暂存到temp 中 */low = 0;high = i - 1;while (low <= high) /* 在有序子序列中折半查找插入位置 */{mid = (low + high) / 2;if (temp < a[mid])high = mid - 1;elselow = mid + 1;}for (j = i - 1; j > high; j--)a[j + 1] = a[j]; /* 将关键字>temp 的记录后移 */a[high + 1] = temp; /* 插入 */}}
注:折半查找是先比较找到位置然后一起移动,因此比较次数并不比直接插入少。

0 0
原创粉丝点击