shell排序(希尔排序)

原理:

        通过减少复杂度来提高效率,利用一个“增量(可以是任意数)”来构成一个增量序列,进而实现数组中的数据进行跳跃式比较,从而减少普通排序中反复比较的次数。

#include <stdio.h>
#include "sort.h"//这里我自己写的头文件

//顺序表的shell排序
void shell_sort(sqlist *sq)
{
    int increment = 0;
    increment = sq->length;//初始化一个增量
    int i,j;
    do{
        increment = increment/3 + 1;//增量序列(increment/3可根据数据的大小适当调整)
        for(i = increment+1;i <= sq->length;i++)//从增量的数据开始遍历后面的每一个数据
        {
            if(sq->data[i] < sq->data[i-increment])//将数组中的数据跳跃式比较
            {
                sq->data[0] = sq->data[i];//规定数据中的第一个元素不存数据,作为中间变量
                for(j = i-increment;j > 0 && sq->data[j] > sq->data[0];j -= increment)
                {
                    sq->data[j+increment] = sq->data[j];
                }
                sq->data[j+increment] = sq->data[0];
            }//该if语句实现两个数据的交换
        }
    }while(increment > 1);//这里最后一次结束要让increment=1
}

以上代码举例:

1.传入数组arr[10] = {0, 81, 98, 14, 70,  3, 81, 19, 59,  5}(我们规定0号元素不存数据作为中间值,暂存为0),其中length = 9。

2.进入该函数中,increment初始值为9,这时第一次进入do循环。

3.increment = 4,进入for循环中,(i=5;i<=9;i++)相当于从5开始遍历数组到末尾,

4,进入for循环后开始比较,arr[5]=3 < arr[1]=81----交换;arr[6]=81 < arr[2]=98----交换;arr[7]=19 > arr[3]=14----不交换;arr[8]=59 < arr[4]=70----交换;arr[9]=5 < arr[5]=81----交换。第一次循环结束,此时arr[10] = {0,3,81,14,59,5,98,19,70,81}。

5,increment=4>1,第二次进入do循环,increment=2,进入for循环,i=3,即arr[3]=14 > arr[1]=3----不交换;arr[4]=59 < arr[2]=81----交换;arr[5]=5 < arr[3]=14----交换;arr[6]=98 > arr[4]=81----不交换;arr[7]=19 > arr[5]=14----不交换;arr[8]=70 < arr[6]=98----交换;arr[6]=70 < arr[4]=81----交换;arr[9]=81 > arr[7]=19----不交换。此时arr[10]={0,3,59,5,70,14,81,19,98,81}。

6,increment=2>1,第三次进入do循环,increment=1,进入for循环,i=2,即arr[2]=59 > arr[1]=3----不交换;arr[3]=5 < arr[2]=59----交换;arr[4]=70 > arr[3]=59----不交换;arr[5]=14 > arr[4]=70----交换;arr[4]=14 > arr[3]=59----交换;arr[6]=81 > arr[5]=70----不交换;arr[7]=19 < arr[6]=81----交换;arr[6]=19 > arr[5]=70----交换;arr[5]=19 > arr[4]=59----交换;arr[9]=81 < arr[8]=98----交换。

此时arr[10]={0,3,5,14,19,59,70,81,81,98}.

7,increment=1,结束循环。

代码结果:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值