码迷,mamicode.com
首页 > 编程语言 > 详细

插入排序

时间:2016-04-30 10:08:42      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

    插入排序是一种简单直观的排序方法,其基本思想在于每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成。

1. 直接插入排序

基本思想:

    直接插入排序是一种最简单的排序方法,它的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增加1的有序表。

技术分享
 1 #include <iostream>
 2 using namespace std; 
 3 
 4 void insertSort(int A[], int n)
 5 {
 6     int i, j; 
 7     for (i = 2; i <= n; i++) // 依次将A[2]~A[n]插入到前面已排序序列
 8     {
 9         if (A[i] < A[i-1]) // 若A[i]的关键码小于其前驱,需将A[i]插入有序表 
10         {
11             A[0] = A[i]; // 复制为哨兵
12             for (j = i-1; A[0] < A[j]; j--) // 从后往前查找待插入位置 
13                 A[j+1] = A[j]; // 向后挪位
14             A[j+1] = A[0]; // 复制到插入位置 
15         } 
16     }
17 }
18 
19 int main(int argc, char *argv[])
20 {
21     int arr[] = {-1, 99, 88, 33, 66, 77, 44, 102, 35, 47, 25}; 
22     insertSort(arr, 10);  
23     for (int i = 1; i <= 10; i++) cout << arr[i] << " "; 
24     cout << endl; 
25     
26     return 0; 
27 }
View Code

效率分析:

    直接插入排序的时间复杂度O(n2),空间复杂度O(1);

    在最好的情况下,表中元素已经有序,此时每插入一个元素,都只需要比较一次而不用移动元素,因而时间复杂度为O(n)。

    稳定性:每插入一个元素时总是从后向前先比较再移动,所以不会出现相同元素相对位置发生变化的情况,即直接插入排序是一个稳定的排序方法。

2. 希尔排序

基本思想:

    希尔排序的基本思想是:先将待排序表分割成若干形如L[i, i+d, i+2d, ..., i+kd]的“特殊”子表,分别进行直接插入排序,当整个表中元素已呈“基本有序”时,再对全体记录进行一次直接插入排序。希尔排序的排序过程如下:

    先取一个小于n的步长d1,把表中全部记录分成d1组,所有距离为d1的倍数的记录放在同一个组中,在各组中进行直接插入排序;

    然后取第二个步长d2,重复上述过程,直到所取到的dt=1,即所有记录已放在同一组中,再进行直接插入排序,由于此时已经具有较好的局部有序性,故可以很快得到结果。

    到目前为止,尚未求得一个最好的增量序列,希尔提出的方法是d1=n/2,di+1=[di/2],并且最后一个增量是1。

    一趟增量为dk的希尔插入过程如下:

技术分享
 1 void shellInsert(int A[], int n, int dk)
 2 {
 3     int i, j; 
 4     for (i = dk+1; i <= n; i++)
 5     {
 6         if (A[i] < A[i-dk]) // 需要将A[i]插入有序增量子表 
 7         {
 8             A[0] = A[i];  // 暂存在A[0] 
 9             for (j = i-dk; j > 0 && A[0] < A[j]; j -= dk)
10                 A[j+dk] = A[j];  // 记录后移,查找插入位置 
11             A[j+dk] = A[0]; // 插入 
12         }
13     }
14 }
View Code

    通过多次调用一趟希尔插入过程,我们可以将表最终排列为有序。希尔排序算法如下:

技术分享
1 void shellSort(int A[], int n, int dlta[], int t)
2 { // 按增量序列dlta[0..t-1]对A作希尔排序 
3     int k; 
4     for (k = 0; k < t; k++)
5         shellInsert(A, n, dlta[k]);  
6 } 
View Code

效率分析:

    空间复杂度:O(1)。

    时间复杂度:由于希尔排序的时间复杂度依赖于增量序列的函数,这涉及数学上尚未解决的难题,所以其时间复杂度分析比较困难。当n在某个特定范围时,希尔排序的时间复杂度约为O(n1.3)。在最坏情况下希尔排序的时间复杂度为O(n2)。

    稳定性:当相同的关键字的记录被划分到不同的子表时,可能会改变它们的相对次序,因此,希尔排序是一个不稳定的排序方法。例如,表L={3, 2, 2},经过一趟排序后,L={2, 2, 3},最终排序序列也是{2, 2, 3},显然,2与2的相对次序已经发生了变化。

 

插入排序

标签:

原文地址:http://www.cnblogs.com/xiaoxxmu/p/5448222.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!