算法导论之插入排序

来源:互联网 发布:qq三国js副本五虎技能 编辑:程序博客网 时间:2024/05/16 17:55

排序问题

输入: n个数的一个序列< A1,A2 , … , An >。
输出: 序列的一个排列< A1’ , A2’ , … , An’ >, 满足A1’ <= A2’ <= … <= An’ , 或者 A1’>= A2’ >= … >= An’ 。

插入排序

1. 原理简述

使用插入排序来排序手中的扑克牌

  • 在未排序的数中取出一个数(从乱糟糟的牌堆里拿出一张牌)
  • 将它插入到已经排好序的子集的正确位置中(将它插入手中已经排好顺序的牌中,得到新的排好顺序的牌)
  • 再取出一个数,将它插入到正确位置(再从乱糟糟的牌堆里拿出一张牌)
  • 依次类推,直到序列里所有的数都插入到正确的位置。

2. 伪代码

INSERTION_SORT(A)    for j = 2 to A.length         key = A[j]        //insert A[j] into the sorted sequence A[0...j-1]        i = j-1        while i > 0 and A[i] > key          A[i+1] = A[i]          i = i-1        A[i+1] = key

3. 理解伪代码

  • 假设数组下标从1 开始,数组总共有n个数。
  • 排序方式是 升序排序
  • 对于序列中的第2至最后一个数,我们从取出第j个数(j 从 2 到 n),将其保存在一个 key 临时变量中,这样,第j个位置就‘空’了出来
  • 对于A[0…j-1], 最开始时是[ A1 ], 只有一个数,所以它必定是排好序的。
  • 从第 j-1 到 第1 个数,依次和 key 比较,如果大于key ,那就把它搬到右边的位置。
  • 当不再有 大于key 的数时,空出来的位置刚好是最适合key的,将key 插进去,便得到一个新的排好顺序的序列。
  • 循环执行以上步骤,直到将第n 个数插入到正确的位置。

  • 对于 A[5,2,4,6,1,3] 的排序,过程如下图所示

这里写图片描述

4. C语言实现

整型数的插入排序,输出结果可选择升序或降序

  1. 头文件, sort.h
    #ifndef __SORT_H__    #define __SORT_H__    void Insert_Sort_Integer(int array[], int length, unsigned char isAscending);    #endif 
  1. C 文件, sort.c
    #include "sort.h"    /*  插入排序  */    void Insert_Sort_Integer(int array[], int length, unsigned char isAscending)    {        int i, j;        int temp;        for (i = 1;i < length; i++)        {            temp = *(array + i);            j = i - 1;            if(isAscending)            {                while (j >= 0 && *(array + j) > temp)                {                    array[j + 1] = array[j];                    j--;                }            }            else             {                while (j >= 0 && *(array + j) < temp)                {                    array[j + 1] = array[j];                    j--;                }            }            *(array + j + 1) = temp;        }    }

结语

插入排序属于原址排序,但它的时间复杂度是O(n^2),和冒泡排序同样的时间复杂度,效率比较低,使用较少, 后面将介绍 归并排序,堆排序,快速排序