• 插入排序的改进算法希尔排序


      希尔排序(Shell's Sort)又称缩小增量排序,类属于插入排序。考虑到直接插入排序得一下特点:

               (1)在待排序数基本有序情况下排序效率大大提高;

                (2)在n很小时,其排序效率也很高。

         基于以上考虑,对直接插入排序进行改进,并得出希尔排序。其基本思想为:先将整个待排序记录序列分割成若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序时”,再对全体记录进行一次插入排序。

        这里的子序列是通过一个增量得到的,每一次赋予不同的增量,则得到不同的子序列组(分别对子序列进行直接插入排序就称作一次希尔插入排序,注意,实际代码中并不是依次排好一个自序列之后再排下一个这样效率低,而是依次扫描每一个子序列的元素即同时对各子序列排序)。这样将该增量逐渐递减为1便最终得到的子序列组就是其本身。

        此时,问题的关键就在于增量序列delta[t]了,其个数和值都将影响排序效果。已有的结论为:当delta[k]=2t-k+1-1,1≤k≤t≤log2(n+1)时其时间复杂度为O(n3/2).另外增量序列还有其他各种取法。

        另外,从排序过程可知,希尔排序是一种不稳定的排序算法。

       对此,源码如下:

    #include <iostream>
    #include <time.h>
    #include <math.h>
    #include <cstdlib>
    #include <fstream>
    #include <stdio.h>
    
    using namespace std;
    
    template <typename T>
    void shellInsert(T &L,int dk, int length)
    //对顺序表做一趟希尔排序,dk是增量值,length是待排序数组的元素个数
    {
        int i=0,j=0;
        for (i = 1+dk; i <= length; ++i)
            if (L[i] < L[i-dk])
            {
                L[0] = L[i]; //L[0]用来临时暂存
                for (j = i-dk; j>0 && L[j]>L[0]; j -= dk)
                    L[j+dk] = L[j];
                L[j+dk] = L[0];
            }
    }
    
    template <typename T>
    void shellSort(T &L, int dlta[], int t,int length)
    {
        for (int k = 0; k<t; ++k)
        {
            shellInsert(L,dlta[k],length);
            /*for (int i = 1; i<=length; ++i)
                cout << L[i] << ' ';
            cout << endl;*/
        }
    }
    
    int main()
    {
    
        srand(time(NULL));
        int n,n1,i=0;
        cout << "输入待排序数组的个数:";
        cin >> n;
        int* a = new int[n];
        //int* a = (int *) malloc(n*sizeof(int));
        n1 = log(double(n))/log(2.0);//增量序列的大小
        int* dlta = new int[n1];
        //const size_t int_a_size = sizeof(a)/sizeof(a[0]);
        for (i = 0; i<n1; ++i) //生成增量序列
        {
            dlta[i] = pow(2.0,n1-i)-1;
            cout << dlta[i] << ' ';
        }
        cout << endl;
        for (i = 1; i<n; ++i) //生成待排序数组
        {
            a[i] = double(rand())/(RAND_MAX+1)*n;
            cout << a[i] << ' ';
        }
        cout << endl << endl;
    
        shellSort(a,dlta,n1,n-1);
        ofstream outs;
        outs.open("shellSort.txt");
        for (i = 1; i<n; ++i)
        {
            outs << a[i] << ' ';
            if (0 == i%11)
                outs << endl;
            //cout << a[i] << ' ';
        }
        cout << endl;
        return 0;
    }

        

  • 相关阅读:
    java7底层源码
    google的collection
    2017年八大顶尖的技术趋势
    【译】STM32L4x6系列用户手册第四章
    FRDM-KL43开发板驱动段式液晶SLCD的实现方法
    如何根据丝印查找相关的产品型号
    Arduino Tian开发板:一个功能强大的天气预报中心
    在STM32F746G-DISCO开发板上使用Nabto + FreeRTOS的演示热泵应用
    为LPC1549 LPCXpresso评估板开发基于mbed的项目
    使用LPCXpresso开发板调试外部的电路板
  • 原文地址:https://www.cnblogs.com/lyfruit/p/3003616.html
Copyright © 2020-2023  润新知