希尔排序c语言实现

希尔排序 希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。直接插入排序 有一个问题如果待排序列中,顺序恰好是逆序,如果用直接插入排序,那将耗费大量的代价,每次都要移动大量 数据,付出非常惨重的代价。 因此 就诞生了 希尔排序, 这个排序方法,可以算是对 插入的一种改进。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。


排序思想: 先把 待排序列 分成若干组,对这若干组进行 插入排序,这样就 一部分 就先有序了, 之后 对这个组 在重新 划分 更小的若干组,进行插入排序, 直到组为1 的时候,退化为  直接插入排序。 




初始时,有一个大小为 15 的无序序列。
(1)在第一趟排序中,我们不妨设 gap1 = N / 2 = 7,即相隔距离为 7 的元素组成一组,可以分为 5 组。
(2)接下来,按照直接插入排序的方法对每个组进行排序。
在第二趟排序中,我们把上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 3 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为 2 组。
(3)按照直接插入排序的方法对每个组进行排序。
(4)在第三趟排序中,再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为 1 的元素组成一组,即只有一组。
(5)按照直接插入排序的方法对每个组进行排序。此时,排序已经结束。

下面 看一个例子:

int arr[]={1,34,6,21,98,31,7,4,36,16,47,67,37,25,2}
len=15 ,  gap=len/2
相同颜色代表一组.

1    4  2

34   36

6    16

21   47

98   67 

31   37

7    25
 
 

先 组内 排序 为: {1 2 4},{34 36},{6 16},{21 47},{67 98},{31 37},{7 25}





下面看代码:

第一种实现 如下:

d  就是 gap  这个变量 


#include "stdio.h"
#include "stdlib.h"
#include "string.h"

void printArray(int array[], int len)
{
    int i = 0;
    for(i=0; i<len; i++)
    {
        printf("%d ", array[i]);
    }

    printf("\n");
}



void  shell_sort(int array[], int len){
    int d = len;
    while (1){
        d = d/2;
        for (int x=0;x<d;x++){
            for (int i = x+d; i < len; i=i+d)
            {
                
                int  k = i ;
                int temp = array[k];
                for (int j = i-d;j>=0 && array[j]>temp;j =j-d)
                {
                   array[j+d] =array[j];
                   k = j ;
                }
                array[k] = temp ;
            }
            
        }
        if (d ==1)//gap==1,跳出循环  
        {
            break;
        }
    }
}


int main()
{
    
   
    int array[]={1,34,6,21,98,31,7,4,36,25,2};
    int len = sizeof(array) / sizeof(*array); 

    //printArray(array, len);
    shell_sort(array, len);
    printArray(array, len);

    system("pause");
    return 0;
}

看看第二种实现

把 组内排序 写成一个函数 ,这样看的更清楚一些。

#include "stdio.h"
#include "stdlib.h"

void printArray(int array[], int len)
{
	int i = 0;
	for(i=0; i<len; i++)
	{
		printf("%d ", array[i]);
	}

	printf("\n");
}


void group_sort(int  array[], int len, int d,int x){
    /*
        array 数组的指针
        len   数组的长度
        d     组的步长 gap 
	x     组的起始位置
    */
    for (int i = x+d; i < len; i=i+d)
    {
        int  k = i ;
        int temp = array[k];
        for (int j = i-d;j>=0 && array[j]>temp;j=j-d)
        {
           array[j+d] =array[j];
           k = j ;
        }
        array[k] = temp ;
    }

}




/*
 * 希尔排序
 *
 * 参数说明:
 *     array -- 待排序的数组
 *     len -- 数组的长度
 */
void shell_sort(int array[], int len)
{
    int i,gap;

    // gap为步长,每次减为原来的一半。
    for (gap = len / 2; gap > 0; gap /= 2)
    {
        // 共gap个组,对每一组都执行直接插入排序
        for (i = 0 ;i < gap; i++){
	    group_sort(array, len,  gap,i);
	}
        
    }
}



int main()
{
	int array[]={1,34,6,21,98,31,7,4,36,25,2};
	int len = sizeof(array) / sizeof(*array); 
	//printArray(array, len);
	shell_sort(array, len);
	printArray(array, len);

	system("pause");
	return 0;
}

结果如下:




总结: 希尔排序 在一定程度 上减少了 交换次数, 但是这个和d 的递减因子有关。非常牛逼的算法,在此记录一下,如果有疑问可以一起讨论,交流。


参考文档:

c语言实现 shell 排序 
http://www.cnblogs.com/denglw/p/6785654.html
希尔排序算法(排序详解) java 实现 
http://blog.csdn.net/qq845579063/article/details/51447404
希尔排序详解
http://blog.csdn.net/z3881006/article/details/61922109
http://www.cnblogs.com/chengxiao/p/6104371.html  
希尔排序 http://blog.csdn.net/MoreWindows/article/details/6668714   
白话shell排序 http://www.cnblogs.com/skywang12345/p/3597597.html#a1




       分享快乐,留住感动。           2017年 10月 18日 星期三 12:21:13   ----biaoge             

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值