插入排序(直接插入排序,希尔排序)

插入排序

基本思想:每步将一个待排序的记录,按期关键码的大小插入前面已经排序的文件中适当位置,知道全部插入完为止

适应范围:少量数据的排序;

特点:稳定;

时间复杂度:O(N^2)

空间复杂度:O(1)


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


当前元素的前面元素均为有序,要插入时,从当前元素的左边开始往前找从后往前找),比当前元素大的元素均往右移一个位置,最后把当前元素放在他应该在的位置就行了。


比如对1 3 2 4 0 进行排序 (i 为要进行插入有序数列的数字下标值)过程如下:

插入排序(直接插入排序,希尔排序)

代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//直接插入排序
void Insert_Sort(int* a, size_t size)
{
    assert(a);
     
    for (int i = 1; i < size; i++) //第一个数肯定是有序的,从第二个位置开始遍历
    {
        int j = 0;
        int tmp = a[i];
         
        //前i-1个数已经是有序的,所以当a[j] > tmp时,只要将a[j]向后移动一位
        for (j = i - 1; j >= 0 && tmp < a[j]; j--) 
        {
            a[j + 1] = a[j];
        }
         
        a[j + 1] = tmp;
    }
}

测试:

1
2
3
4
5
6
7
8
9
10
void TestInsertSort()
{
    int a[5] = { 1, 3, 2, 4, 0 };
    Print(a, 5);
    cout << endl;
    Insert_Sort(a, 5);
    Print(a, 5);
    cout << endl;
 
}

  

    希尔排序Shell's Sort)又称“缩小增量排序”,他也是一种插入排序类的方法,但在时间效率上较直接插入排序有较大的改进。

   增量的选择: 本文采用增量为(n/3)+1,依次递推,每次增量为原先的(n/3)+1,直到增量为1;

比如对

1
49, 38, 65, 97, 76, 13, 27, 49, 55, 4

进行排序:过程如下

插入排序(直接插入排序,希尔排序)

插入排序(直接插入排序,希尔排序)

插入排序(直接插入排序,希尔排序)

代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Shell_Sort(int* a, size_t size)
{
    assert(a);
 
    int gap = size;
    while (gap > 1)
    {
        gap = (gap / 3) + 1;
        for (int i = gap; i < size; i++)
        {
            int index = i;
            int tmp = a[index];
            int end = index - gap;
 
            while (end >= 0 && tmp < a[end])
            {
                a[end + gap] = a[end];
                end -= gap;
            }
            a[end + gap] = tmp;
        }
    }
}

测试:

1
2
3
4
5
6
7
8
9
10
void TestShell_Sort()
{
    int a[10] = { 49, 38, 65, 97, 76, 13, 27, 49, 55, 4 };
    Print(a, 10);
    cout << endl;
 
    Shell_Sort(a, 10);
    Print(a, 10);
    cout << endl;
}


上一篇:MaxCompute使用指南|阿里云产品内容精选(二十四)


下一篇:2014秋C++第11周项目4参考-特殊三位数