数据结构之希尔排序

希尔排序又称缩小增量排序,它也属于插入排序,但在时间复杂度上改进较大。

推荐视频:

武汉大学李春葆《数据结构》
https://www.icourse163.org/learn/WHU-1001539003#/learn/announce

在希尔排序过程中,可以看到直接插入排序的影子,将直接插入排序中的1改为dk,稍作改动就可以得到希尔排序if语句中的代码:

直接插入排序部分代码:

int j;
for(int i = 2;i<=L.length;i++) 
	if(L.rec[i].key < L.rec[i-1].key) 
	{
	    L.rec[0] = L.rec[i];
	    L.rec[i] = L.rec[i-1];
		for(j = i-1; L.rec[0].key<L.rec[j].key; j--) 
		    L.rec[j+1] = L.rec[j];
		L.rec[j+1] = L.rec[0];
	} 

希尔排序部分代码
int j;
for(int i = dk+1;i<=L->length;i++)
	if(L->rec[i].key < L->rec[i-dk].key)
    {
		L->rec[0] = L->rec[i];
		for(j = i - dk;j>0&&L->rec[0].key<L->rec[j].key;j-=dk)
			L->rec[j+dk] = L->rec[j];
		L->rec[j+dk] = L->rec[0];
	}

 

希尔排序实例:

//希尔排序
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 20

typedef struct{ //记录类型 
	int key;    //关键字 
	char data;  //数据
}record;

typedef struct{
	record rec[MAXSIZE+1]; //包含MAXSIZE+1个记录,记录0是哨兵,相当于tmp 
	int length;            //顺序表的长度 
}sqList;

void shellSort(sqList *L,int dlta[],int t);//希尔排序函数声明 
void shellInsert(sqList *L,int dk);//希尔排序插入函数声明 

int main()
{
	sqList L; 
	L.length = MAXSIZE; 
	
	//生成希尔排序增量数组及数组长度 
	int *dk = (int*)malloc(sizeof(int));
	int lenDk = 0;
	for(int i = 0,j = L.length;j != 1;i++)
	{
		dk[i] = j/2;
		lenDk++;
		j = j/2;
	} 
	
	//使用随机数据初始化sqList中的数据
	for(int i = 1;i<=L.length;i++)  
	{
		L.rec[i].key = rand()%23;
		L.rec[i].data = 'a' + L.rec[i].key; 
	}
	
	//输出排序前的记录 
	for(int i = 1;i<=L.length;i++)
		printf("record %2d: key = %2d, data = %c\n",i,L.rec[i].key,L.rec[i].data);
	
	//希尔排序
	shellSort(&L,dk,lenDk);
	
	//输出排序后的记录 
	printf("\n------>希尔排序后<------\n");
	for(int i = 1;i<=L.length;i++)
		printf("record %2d: key = %2d, data = %c\n",i,L.rec[i].key,L.rec[i].data);
	
	return 1;
} 

void shellSort(sqList *L,int dlta[],int t)//希尔排序函数
{
	for(int k = 0;k<t;++k)
		shellInsert(L,dlta[k]);
} 

void shellInsert(sqList *L,int dk) //插入元素
{ 
	int j;
	for(int i = dk+1;i<=L->length;i++)
		if(L->rec[i].key < L->rec[i-dk].key){
			L->rec[0] = L->rec[i];
			for(j = i - dk;j>0&&L->rec[0].key<L->rec[j].key;j-=dk)
				L->rec[j+dk] = L->rec[j];
			L->rec[j+dk] = L->rec[0];
		}
}

测试结果:

record  1: key = 18, data = s
record  2: key = 21, data = v
record  3: key =  9, data = j
record  4: key =  4, data = e
record  5: key = 10, data = k
record  6: key = 15, data = p
record  7: key =  1, data = b
record  8: key = 10, data = k
record  9: key =  6, data = g
record 10: key = 15, data = p
record 11: key =  1, data = b
record 12: key = 16, data = q
record 13: key =  5, data = f
record 14: key = 14, data = o
record 15: key =  2, data = c
record 16: key =  8, data = i
record 17: key =  5, data = f
record 18: key =  5, data = f
record 19: key = 20, data = u
record 20: key =  8, data = i

------>希尔排序后<------
record  1: key =  1, data = b
record  2: key =  1, data = b
record  3: key =  2, data = c
record  4: key =  4, data = e
record  5: key =  5, data = f
record  6: key =  5, data = f
record  7: key =  5, data = f
record  8: key =  6, data = g
record  9: key =  8, data = i
record 10: key =  8, data = i
record 11: key =  9, data = j
record 12: key = 10, data = k
record 13: key = 10, data = k
record 14: key = 14, data = o
record 15: key = 15, data = p
record 16: key = 15, data = p
record 17: key = 16, data = q
record 18: key = 18, data = s
record 19: key = 20, data = u
record 20: key = 21, data = v

--------------------------------
Process exited after 0.08636 seconds with return value 1
请按任意键继续. . .

 

posted @ 2019-08-29 17:10  昨夜昙花  阅读(42)  评论(0)    收藏  举报