算法导论之插入排序

排序问题

输入: 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),和冒泡排序同样的时间复杂度,效率比较低,使用较少, 后面将介绍 归并排序,堆排序,快速排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值