首页 > 试题广场 >

回答下面问题

[问答题]

设有关键字序列33,56,12,65,32,19,87,43,11,12,20,采用步长为4,2,1的希尔排序法进行排序

(1) 请写出希尔排序的原理

(2) 写出希尔排序过程

(3) 希尔排序法是否是稳定的排序法(请说明原因)?

//
// Created by John on 2021/02/22.
//希尔排序
//需要注意的一点是array[0]用来做缓存数据了,所以在传入测试了时候,array[0]设置了0
//
template<class T>
void shellSort(T& array){
    int n = sizeof(array)/sizeof(array[0]) - 1;//待排序个数
    int dk,i,j;
//    for(dk = n/2;dk >= 1; dk = dk/2){//步长变化
//如果不设置步长,就默认以待排序个数/2设置初始步长
    for(dk = 4;dk >= 1; dk = dk/2){//步长变化
        //注意代码实现的思路没有按照动画演示的时候整组来,而是通过遍历dk+1的位置到n的位置,依次向前跨步长
        //进行插入排序,这也因此让下面要先进行一次if判断,因为会出现同一组的前面部分已经直接插入排序好了,我们只需要比较最后一个,如果小的话
        //就要进行排序,否则就直接原地不动
        for(i = dk + 1; i <= n; ++i){//每次先从dk+1的位置开始往前插入排序
            if (array[i] < array[i - dk]){
                array[0] = array[i];//缓存当前要插入的值
                for (j = i - dk; j > 0 && array[0] < array[j]; j -= dk) {//往前遍历插入,如果j<=0,说明这个值在当前组最小,要排到这组第一个
                    array[j + dk] = array[j];
                }
                array[j + dk] = array[0];
            }
        }
    }
}
测试:
  int b[] = {0,33,56,12,65,32,19,87,43,11,12,20};
    shellSort(b);
    for(int i = 0; i < sizeof(b)/sizeof(b[0]);i++){
        cout<<b[i]<<" ";
    }

打印结果:
33 11 12 12 19 20 32 33 43 56 65 87
Process finished with exit code 0

再次声明,第一个位置的值不用管,因为是代码中他是用来缓存要插入的值的,最后一次执行插入排序刚好是33,所以缓存了33


发表于 2021-02-22 01:36:34 回复(0)
希尔排序先划分步长,之后步长内部使用插入排序,每趟排序后都步长/2。是不稳定的算法,看第一趟排序,后面的12已经调转到前面的12之前,因此不稳定。
发表于 2020-04-29 17:33:32 回复(0)