希尔排序练习(Shell's sort)

  1. 目的
    进行希尔排序练习。明白希尔排序原理。
    希尔排序:将间隔d的元素视为待排序数组,对该数组进行插入排序。然后逐步缩小d的值,最后直到d=1。这个特点又可以称呼希尔排序为缩小增量排序。
    d=1时为直接插入排序。
    d值的取法一般为折半获取,即每次排序完成,d=d/2。初始d=n/2。
  2. 代码
    实现代码:
        void ShellSort(T testArray[], int nSize){
            LogInfo<T> log = LogInfo<T>();
            T key;//哨兵值
            int times(0), i(0),j(0),d(0),k(0), compare(0), move(0);//记录遍历次数,比较次数,移动次数
            log.ShowState("原始数组为 :");
            log.ShowArray(testArray, nSize);
            //折半d,d为偶数,则加1,排除0
            //d = nSize / 2;
            //d=d != 0 && d % 2 == 0 ? d + 1 : d;
            //for (d; d >=1; d=d/2,d=d!=0&&d%2==0?d+1:d){
            for (d = nSize / 2; d >= 1;d=d/2){
                compare++;
                times++;
                for (k = 0; k < d; k++)
                {
                    //以d间隔的第一轮排序
                    for (i = k+d; i < nSize; i = i + d){
                        if (testArray[i] < testArray[i - d]){
                            key = testArray[i];//记录待排元素作为哨兵
                            for (j = i - d; j >= 0 && key < testArray[j]; j = j - d){
                                compare++;
                                testArray[j + d] = testArray[j];
                                move++;
                            }
                            testArray[j + d] = key;
                            move++;
                        }
                    }
                }
                log.ShowState("第", times, "趟数组为:");
                log.ShowArray(testArray, nSize);
            }
            log.ShowState("最终数组为 :");
            log.ShowArray(testArray, nSize);
            log.ShowState("比较次数:", compare);
            log.ShowState("  移动次数:", compare);
            log.ShowLine();
        };

测试代码:

#include<iostream>
#include"Test.h"
#include"Sort.h"
#define N_MAX 7
int main()
{
    using namespace Test;
    using namespace MyAlgorithm;
    using namespace std;

    LogInfo<double> log = LogInfo<double>();
    Sort<double> sortTest = Sort<double>();
    log.ShowState("测试希尔排序");
    log.ShowLine();
    log.ShowState("测试正序数组========================");
    log.ShowLine();
    TestDataCreator<double, N_MAX> testArray = TestDataCreator<double, N_MAX>(PositiveArray);
    sortTest.ShellSort(testArray.GetArray(), testArray.GetSize());
    log.ShowState("测试降序数组========================");
    log.ShowLine();
    testArray = TestDataCreator<double, N_MAX>(NegativeArray);
    sortTest.ShellSort(testArray.GetArray(), testArray.GetSize());
    log.ShowState("测试随机数组========================");
    log.ShowLine();
    testArray = TestDataCreator<double, N_MAX>(RandomArray);
    sortTest.ShellSort(testArray.GetArray(), testArray.GetSize());
    int nWait;
    cin >> nWait;
    return 0;
}

输出结果截图:
这里写图片描述

  1. 遇到难题
    1)网络上算法看了很难懂,但是比较简洁,没有仔细深究,最后仔细研究才明白希尔算法原理。代码尽管不简洁但是很能表述算法原理。
    2)希尔算法的证明,没有查询到相关资料,起初无法证明,后来自思考,不管希尔排序怎么排序,最终都有d=1这个步骤,这个步骤是直接插入排序,因此该算法正确。根本不需要证明希尔算法,只需证明希尔算法的优点,这个优点只能从定性上表述,以及实际测试表明。数学证明比较困难,自己知识不足。
  2. 经验
    1)希尔排序有点是移动次数相对较少,为什么会这样,有一种无序命中的感觉吧。在有序的世界里,你总是从一个列表中一一去寻找,挪动。无序的世界里,希尔排序增大了一种可能性,这个元素恰好在这个位置上的概率。
    2)该排序算法时间复杂度为O(n^s) s(1,2),平均复杂度为nlogn。不稳定。空间复杂度O(1)。
    3)算法优点:算法较简单,代码短,需要的空间小,速度还可以,适合情况复杂的排序,适合中小规模的排序
    算法缺点:速度偏慢,不够智能,不适合情况简单的排序,不适合大规模排序。
  3. 后续
    1)进行选择排序练习。
    2)分析网络上流行的希尔排序。该任务暂时搁置,放在所有种类排序算法之后进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值