Shell排序法(对插入排序法的改进)(数据结构)

问题引入

        插入排序法由未排序的后半部前端取出一个值,插入已排序前半部的适当位置,概念简单但速度不快。为加快插入排序法速度,让后一次的排序尽量利用前一次排序后的结果,以加快排序的速度,即采用Shell排序法。

问题分析

        shell排序法过程如下:

        假设要排序的元素有n个,每次进行插入排序时并不是所有的元素同时进行时,而是取一段间隔。Shell首先将间隔设定为n/2,然后跳跃进行插入排序;再将间隔n/4,跳跃进行排序动作;再设定间隔为n/8、n/16等,直到间隔为1之后的最后一次排序终止。由于上一次的排序动作都会将 固定间隔内的元素排序好,所以间隔越来越小时,某些元素位于正确位置的机率越高,因此靠后的排序会较快。

        例如:

                        89 12 65 97 61 81 27 2 61 98

        总共10个数,第一次将间隔设定为10 / 2 = 5,此时对间隔为5的数字进行排序,如下所示(连线部分表示要一起进行排序的部分):

        再将间隔设定为5 / 2的商,也就是2,此时对间隔为2的数字进行排序,如下所示(连线部分表示要一起进行排序的部分):

         再设定为间隔为2 / 2 = 1,此时对间隔为1的数字进行排序,相当于进行一次插入排序,如下所示(连线部分表示要一起进行排序的部分),此时基本已成型,不用大幅度排序:

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t; t = x; x = y; y = t;} //宏定义交换元素数据函数SWAP

void shellsort(int[]);
int main(){
	int number[MAX] = {0}; 
	int i;
	srand(time(NULL)); //刷新每次产生的随机数,若无此句,每次随机数相同,亲自尝试一下便知
	printf("排序前:");
	for(i = 0; i < MAX; i++){ 
		number[i] = rand() % 100; //产生0-99的随机数,这里没有采用固定的数组值进行排序,随机生成
		printf("%d ", number[i]);
	}
	shellsort(number);
	return 0;
}


void shellsort(int number[]){ 
	int i, j, k, gap, t;
	gap = MAX / 2;
	while(gap > 0){
		for(k = 0; k < gap; k++){
			for(i = k+gap; i < MAX; i+=gap){ 
				for(j = i - gap; j >= k; j-=gap){
					if(number[j] > number[j+gap]){ 
						//交换元素位置,也可以将交换语句写在函数体内部 
						SWAP(number[j], number[j+gap]);
					}else{
						break;
					}
				}
			}
		}
		printf("\ngap = %d:", gap); 
		for(i = 0; i < MAX; i++){
			printf("%d ", number[i]); 
		}
		printf("\n");
		gap /= 2;
	}
}

运行结果 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等日出看彩虹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值