zoukankan      html  css  js  c++  java
  • 插入排序和它的进化希尔排序

    插入排序的思想是,将序列分为两段序列,前面的序列是有序的,后面的是无序的,不断的将无序的序列中的元素往前面那个序列插入。

    代码描述:(注意,这里的顺序表都是定义成0号位不用,那些接口adt也是相对应的,比如说初始化你传入的元素个数为6,其实开创的是7个元素的空间。)

    //顺序表结构体定义
    typedef struct {
        int * elem;//基址空间
        int length;//当前长度
        int size;//储存容量
        int increment;//扩容的增量
    }SqList;
    
    
    //直接插入算法描述:
    int InsertSort(SqList & L) {
        if (L.elem == NULL) {
            return ERROR;
        }
        int i,j;
    
        //可以这么想,就i到哪哪里之前就已经是有序项了,那i指到1,2,3,4倒数第二个3的时候,
        //1,2,3,这三个都是有序的了,而这时要处理的是4,处理完后,i就指到4,也排好了,所以是i<length
        for (i = 1; i < L.length; i++) {
            if (L.elem[i + 1] < L.elem[i]) {//说明要插到前面去,如果比他大就不用插
                L.elem[0] = L.elem[i + 1];//先放到0那存一下
                L.elem[i + 1] = L.elem[i];
                j = i ;//j初始的位置是有序列的最后一个元素
                while (j - 1 != 0 && L.elem[0] < L.elem[j - 1]) {//j所指的是确定已经比i+1大的了
                    L.elem[j] = L.elem[j - 1];
                    j--;
                }
                L.elem[j] = L.elem[0];
            }
        }
        return OK;
    }

    希尔排序可以理解为普通插入排序的升级版,就它的思路是先把序列变成基本有序,再进行希尔排序。具体操作是按增量d把序列划分为i个子序列,然后分别对这i个子序列进行插入排序,重复这一过程,直至增量d减到1就对这个基本有序的序列进行一次希尔排序。所以其实思路跟插入差不多。

    看代码描述:

    int ShellInsert(SqList & L, int dk) {
    /*将顺序表按增量dk划分为几个子序列,分别对这几个子序列做插入排序*/
        if (L.elem == NULL) {
            return ERROR;
        }
        int i, j;
    
        for (i = 1; i <= L.length-dk; i++) {
            if (L.elem[i + dk] < L.elem[i]) {//说明要插到前面去,如果比他大就不用插
                L.elem[0] = L.elem[i + dk];//先放到0那存一下
                j = i + dk;
                do {
                    j -= dk;
                    L.elem[j + dk] = L.elem[j];//记录后移
                } while (j - dk > 0 && L.elem[0] < L.elem[j - dk]);
                L.elem[j] = L.elem[0];//插入
            }
        }
        return OK;
    }
    
    /*对顺序表进行希尔排序*/
    int ShellSort(SqList & L, int d[], int t) {
        if (L.elem == NULL)return ERROR;
        int k;
        for (k = 0; k < t; k++) {
            ShellInsert(L, d[k]);//一趟增量为d[k]的增量排序,也就是说第一次的增量为3,第二次为1
        }
        return OK;
    }
  • 相关阅读:
    易联云-打印机
    通俗易懂了解Vue中nextTick的内部实现原理
    题解 CF1556E 【Equilibrium】
    题解 P6087 【[JSOI2015]送礼物】
    Redisson分布式锁源码分析
    Java代理模式
    java 8 去重
    jdk 8 list 转map Duplicate key WmSoDetail
    前端单点登录(SSO)
    Linux基础02 bash shell(命令补全, 快捷键, 历史命令, 命令别名alias, ls, man), 目录管理
  • 原文地址:https://www.cnblogs.com/wangshen31/p/7743711.html
Copyright © 2011-2022 走看看