七种排序--------希尔排序(Shell Sort)

希尔排序的基本思想是将距离某个增量的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后的结果是基本有序而不是局部有序。

希尔排序算法代码如下:

void ShellSort(SqList *L)
{
	int i,j;
	int increment = L->length;
	do
	{
		increment = increment/3+1;    //增量序列
		for(i = increment + 1;i<L->length;i++)
		{
		    if(L->r[i]<L->r[i - increment])  //将L->r[i]插入有序增量子表
			{
			    L->r[0] = L->r[i];       //暂存在l->r[0]
			    for(j = i - increment;j > 0 && L->r[0]<L->r[j];j-=increment)
				    L->r[j + increment] = L->r[j];    //记录后移,查找插入位置
			    L->r[j + increment] = L->r[0];    //插入
			}
		}
	}
	while(increment > 1);
}

1.程序开始运行时,此时我们假设传入的SqList参数值为length = 9,r[0] = {0,9,1,5,8,3,7,4,6,2}.这就是我们需要排序的序列。

2.第4行,变量increment就是那个增量,初始值让他等于待排序的记录数。

3.第5~19行是一个do循环,他终止条件是increment不大于1时,其实也就是增量为1时就停止循环了。

4.第7行,这一句很关键,设置增量的距离,距离按照实际情况设定,执行完这里后increment = 4.

5.第8~17行shi是一个for循环,i 从4 + 1 = 5 到 9 结束。

6.第10行,判断r[i]与r[i - increment]的大小,r[5] = 3 小于r[1] = 9 ,满足条件,第12行,将r[5] = 3暂存ru入r[0]中,第13~14行的循环只是为了将r[1] = 9赋值给r[5]由于循环的增量是j-=increment,其实他就循环了一次,此时j = -3。第15行,再将r[0] = 3赋值给r[-3+4] = r[1] = 3,shi'事实上这一段代码就干了一件事,jiu'就是将第5位置的3和第一位置的9进行了交换。

7.循环继续,i = 6,不满足判断条件,不交换数据。

8.循环继续,i = 7,r[7] < r[3],交换两者数据。

9.循环继续,i = 8,r[8] < r[4],交换两者数据。

10.循环继续,i = 9,r[9] < r[5],交换两者数据。有r[5] < r[1],交换两者数据,

最终第一轮循环结束后,数组变为r[] = {2,1,4,6,3,7,5,8,9},此时小的数2,1已经在前面了,大的数8,9已经在后面了,这就向基本有序靠近了一步,然后继续循环,increment继续减小,最终循环下来便会排序完成。

希尔排序复杂度:

时间复杂度O为n的3/2次方,由于记录是跳跃式的移动,希尔排序并不是一种有序的排序方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章