c语言实现希尔排序

自己看书时,对希尔排序的理解一直处于茫然状态,然后在维基百科上看到了这样一句话,再加上这样一个例子,总算消除了我的迷惑。

因为访问危机百科需要翻墙,故复制了了相关内容在本博客里,若读者已翻墙,可以直接点此进入维基百科查看。

--------------------------------------以下内容来源于维基百科--------------------------------------

一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i += step_size而不是i++)。

例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10

然后我们对每列进行排序:

10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45

将上述四行数字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:

10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45

排序之后变为:

10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94
最后以1步长进行排序(此时就是简单的插入排序了)。

--------------------------------------以上内容来源于维基百科--------------------------------------

值得注意的是,在希尔排序里,注意选择增量因子,最后一个增量因子必须是1,其次各增量之间不应该含有公约数,或者说各个增量互素。

下面是我的实现代码,其中考虑了增量排序的问题,避免输入有误。这个代码是为了学习插入排序而写的,本来增量因子排序那个直接插入排序函数是可以省的,我还是写上了。便于与希尔排序做个比较。

#include<stdio.h>

#define MaxSize 100

struct DataType
{
	int data;
};

struct Sqlist
{
	DataType R[MaxSize];
	int length;
};

//直接插入排序对增量因子由大到小排序
void DirectSort(int *da,int n)
{
	int i,j;
	int temp;
	for(i=1;i<n;i++)
	{
		if(da[i-1] < da[i])
		{
			temp = da[i];//设置temp为哨点
			j=i-1;
			
			while(da[j] < temp)
			{
				da[j+1] = da[j];
				j--;
				if(j<0)
				{
					break;
				}
			}
			da[j+1] = temp;
		}
	}
}

void ShellInsert(Sqlist *l,int d)
{
	//对R数组进行希尔排序,d为增长因子
	int i,j;
	for(i=d+1;i<=l->length;i++)
	{
		if(l->R[i].data > l->R[i-d].data)
		{
			//向前寻找插入位置
			l->R[0] = l->R[i];//置哨点

			j = i-d;
			while(l->R[0].data > l->R[j].data)
			{
				l->R[j+d] = l->R[j];
				j=j-d;

				if(j<0)
				{
					break;
				}
			}
			l->R[j+d] = l->R[0];
		}
	}
}

//希尔排序
void ShellSort(Sqlist *l)
{
	//按递增序列对顺序表R数组做希尔排序
	int d[10],t,k;
	printf("\n输入增量因子的个数:");
	scanf("%d",&t);
	printf("由大到小输入每一个增量因子:\n");
	for(k=0;k<t;k++)
	{
		scanf("%d",&d[k]);
	}

	//对增量因子进行排序,以防出错
	DirectSort(d,t);

	for(k=0;k<t;k++)
	{
		printf("%d ",d[k]);
	}

	printf("\n");

	for(k=0;k<t;k++)
	{
		ShellInsert(l,d[k]);
	}
}

int main()
{
	Sqlist list;
	list.length = 10;

	int data[10] = {2,6,1,4,9,6,8,7,3,9};

	//初始化数据
	for(int i=0;i<list.length;i++)
	{
		list.R[i+1].data = data[i];
	}

	ShellSort(&list);

	for(int i=0;i<list.length;i++)
	{
		printf("%d ",list.R[i+1].data);
	}

}

运行截图:



发布了26 篇原创文章 · 获赞 12 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章