插入类排序(直接插入排序、折半插入排序、希尔排序)

一、直接插入排序

1.1 算法思想

完整的直接插入排序是从 i=2 开始的,即将第一个记录视为已排好序的单元素子集合,然后将第二个记录插入单元素子集合中。i 从2循环到n,即可实现完整的直接插入排序。 

绿色部分为已排好序的记录 

监视哨的作用:

1、备份待插入的记录,以便前面关键字较大的记录后移;

2、防止越界。

1.2 算法实现

void InsSort(RecordType r[], int n) {
    int i, j;

    for (i = 2; i <= n; ++i) {
        /* 将待插元素放入暂存单元r[0] */
        r[0] = r[i];
        j = i - 1;
        /* 寻找插入位置 */
        while (r[0].key < r[j].key) {
            r[j + 1] = r[j];
            --j;
        }
        /* 插入待插元素 */
        r[j + 1] = r[0];
    }
}

算法要点:

1、使用监视哨r[0]临时保存待插入的记录;

2、从后往前查找应插入的位置;

3、在同一循环中完成查找和移动。

1.3 算法性能分析 


二、折半插入排序

2.1 算法思想

与直接插入排序的区别在于: 查找插入位置时使用的方法不同。

2.2 算法实现

void BinSort(RecordType r[], int n) {
    int i, j;
    int low, high, mid;

    for (i = 2; i <= n; ++i) {
        /* 将待插元素放入暂存单元r[0] */
        r[0] = r[i];
        /* 折半查找法,确定插入位置 */
        low = 1; high = i - 1;
        while (low <= high) {
            mid = (low + high) / 2;
            if (r[0].key < r[mid].key)
                high = mid - 1;
            else
                low = mid + 1;
        }
        /* 腾出插入位置 */
        for (j = i - 1; j >= low; --j)
            r[j + 1] = r[j];
        r[j + 1] = r[0];
    }
}

算法要点:

1、使用监视哨r[0]临时保存待插入的记录;

2、使用折半查找法查找应插入的位置;

3、查找完成后,再完成移动。

2.3 算法性能分析 


三、希尔排序

3.1 算法思想

基本思想:将整个待排序记录分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列中的记录基本有序时,对全体记录进行直接插入排序。

颜色相同的记录组成一个子序列 

3.2 算法实现

void ShellInsert(RecordType r[], int n) {
    int i, j, d;

    /* 逐渐缩短步长,直至步长为1 */
    for (d = n/2; d >= 1; d = d/2) {
        /* 对各个子序列进行直接插入排序 */
        for (i = 1 + d; i <= n; ++i) {
            r[0] = r[i]; j = i - d;
            while (j > 0 && r[0].key < r[j].key) {
                r[j + d] = r[j];
                j -= d;
            }
            r[j + d] = r[0];
        }
    }
}

说明:for (i = 1 + d; i <= n; ++i) 循环是穿插着完成所有子序列的直接插入排序的。

处理顺序:

1. 处理第一个子序列的第二个记录; 

2. 处理第二个子序列的第二个记录;

……

d. 处理第d个子序列的第二个记录;

1. 处理第一个子序列的第三个记录; 

2. 处理第二个子序列的第三个记录;

……

d. 处理第d个子序列的第三个记录;

……

直至处理完所有的记录。

3.3 算法性能分析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值