shellsort

通过选取适当的gap能将算法复杂度降低为O(n^(4/3)),不得不说希尔排序也是很棒滴。

/*
 * szlShellSort.h
 */
#ifndef SZL_SHELLSORT_H
#define SZL_SHELLSORT_H

/*
 * 希尔排序
 */
void shellSort(int a[], int n);

#endif

/*
 * szlPower.h
 */
#ifndef SZL_POWER_H
#define SZL_POWER_H

/*
 * 求a的b次方;b>=0
 */
int power(int a, int b);

#endif

/*
 * szlShellSort.c
 */

#include "szlShellSort.h"
#include "szlSwap.h"
#include "szlPower.h"
//#define SZLP(fmt,args...) printf("%s,%d: "fmt"\n",__FUNCTION__,__LINE__,##args)

/*
 * 希尔排序(缩小增量的插入排序算法);是直接插入排序的一个扩展的版本;
 * 可将直接插入排序看成是间距为1的希尔排序;希尔排序的思想是,由于插入排序每次只能将
 * 元素往前移动一个单位,所以效率可能比较低,希尔排序通过设置间距来保证每次可以移动
 * 适当的单位,因此可能提高排序效率;
 * 实践证明,当选取得间距gap的值较为合适时,算法的复杂度为O(n^1.3)及O(n*(lgn)^2)等比较
 * 低的复杂度。
 */
void shellSort(int a[], int n){
  int m=0,i,j,k,gap;
  /*
   * 这里只是选取一种常用的gap;其分析来自wiki;
   * http://en.wikipedia.org/wiki/Shellsort
   * 当gap=1+3*2^(k-1)+4^k时满足O(n^(4/3))的时间复杂度;
   */
  do{
    m++;
    gap=1+3*power(2,m-1)+power(4,m);
  }while(gap<n);
  
  for(m--;m>=1;m--){
    if(1==m){
	  gap = 1;
	}
	else{
	  gap = 1+3*power(2,m-1)+power(4,m);
	}  
      
	for(i=0;i<gap;i++){ //gap为多大,数组就被切割为多少个子数组
	  for(j=i+gap;j<n;j+=gap){ //从每个子数组的下一个元素访问
	    k=j;
	    while(a[k]<a[k-gap]){ //将新近访问到的元素插入到自身的子数组中去
		  swap(&a[k],&a[k-gap]);
		  k-=gap;
		  if(k-gap<i){ //往前访问到第一个元素就要停止往前
		    break;
		  }
		}
	  }
	}
  }
}

/*
 * szlPower.c
 */
#include <assert.h>
#include "szlPower.h"
/*
 * 求a的b次方
 */
int power(int a, int b){
  assert(0<=b);
  if(0==b){
    return 1;
  }
  else if(1==b){
    return a;
  }
  else{
    return a*power(a,b-1);
  }
}

下面是和其他算法的比较,输入的Inut SIZE是输入规模,程序自动生成一个如此大小的一维数组;当其他的算法需要等待很久时,我终止他们的运行。先看输入为1,000、10,000及100,000时的运行情况:



然后是输入为1,000,000及10,000,000的情形:


可以看到,希尔排序在大数据量时还是比较不错的,其运行时间(单位为毫秒)差不多和这些号称是NlgN的算法一样,而其他的基本排序算法(插入排序、选择排序、冒泡排序)几乎不可能运行出来。

当输入规模为100,000,000时,我的电脑已经不够分配空间了,呵呵,所以暂时就不跑了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值