(C语言浙大版)小白实现希尔排序并分析增量序列(附测试用例)


本博文源于浙江大学《数据结构》,今天姥姥讲解希尔排序。希尔排序是对插入排序增量序列的扩展,如何更好的加快排序的速度,有以下的结论需要熟知:

希尔排序复杂度分析:
	最好和最坏都在 T=O(N^2)
	希尔排序不是稳定的,可能把相同元素位置换掉
算法特点:
	
 - 记录跳跃式地移动导致排序方法是不稳定的
 - 只能用于顺序结构,不能用于链式结构。
 - 增量序列可以有各种取法,但应该使增量序列值没有除1之外的公因子,并且最后一个增量必须等于1.
 - 记录总的比较次数和移动次数都比直接插入排序排序要少,当n越大,效果明显,所以希尔排序适合初始无序,n较大时的情况
	

因此,引入增量序列对希尔排序进行优化是显地非常有必要的。

增量序列

在这里插入图片描述
图片是对增量序列的优化,也可以看到在间隔排序后,最后一个1间隔排序的次数大大减少,显得希尔排序看起来非常优秀,因此如何定义出更好的增量排序就成为大牛们的议题了。

增量序列的优化

在这里插入图片描述
这是一个非常囧的案例,在间隔后的排序前三躺竟然啥都没发生。太吃惊了。最后得出定理

定理1 增量元素不互质,则小增量可能根本不起作用

Hibbard增量序列

在这里插入图片描述
这就是对增量序列的一次改进。将增量序列进行优化。

Sedgewick增量序列

在这里插入图片描述
就是用第二行那个计算公式倒出增量序列的公式。也可以试试。

测试用例

int arr[5] = {5,3,1,6,2};

将整型数组里的元素进行排序,5由里面的元素进行改变,并在下面给出希尔排序的源码

源码(教科书版本)

#include<stdio.h>
typedef int ElementType;
void Print_Array(ElementType A[],int N)
{
    printf("\n");
    for(int i=1;i<N;i++)
        printf("%d ",A[i]);
}

void ShellInsert(int arr[],int dk){
  int i,j;
    for(i = dk+1;i<=4;++i){
      if(arr[i]<arr[i-dk]){
          arr[0] = arr[i];
          for(j =i-dk;j>0 && arr[0] < arr[j];j-=dk)
              arr[j+dk] = arr[j];
          arr[j+dk] = arr[0];
      }
  }
}
void ShellSort(int arr[],int dt[],int t){
    for(int k=0;k<t;k++)
        ShellInsert(arr,dt[k]);
}
int main()
{
    int arr[5] = {5,3,1,6,2};
    Print_Array(arr,5);
    int dt[3]={3,2,1};
    ShellSort(arr,dt,3);
    Print_Array(arr,5);
    return 0;

}

源码附上(优化版本)

//希尔排序
#include<stdio.h>
typedef int ElementType;
void Print_Array(ElementType A[],int N)
{
	printf("\n");
	for(int i=0;i<N;i++)
		printf("%d ",A[i]);
}

void Shell_sort(ElementType A[], int N)
{
	int D,i,Tmp,P;
	for(D= N/2;D>0;D/=2) {
		for(P=D;P<N;P++) {
			Tmp = A[P];
			for(i=P;i>=D && A[i-D]>Tmp;i-=D) 
				A[i] = A[i-D];
			A[i] = Tmp;
		}
	}
}
int main()
{
	int arr[5] = {5,3,1,6,2};
	Print_Array(arr,5);
	Shell_sort(arr,5);
	Print_Array(arr,5);
	return 0;
	
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值