插入排序------希尔排序(组内采用折半插入排序)

        Shell排序法又称希尔排序法缩小增量排序法。其基本思想为:先选定一个整数s<n,把待排序文件的所有记录分成s组,所有距离为s的记录分在同一组内,并对每一组内的记录进行排序。然后,更新s的值,重复上述分组和排序的工作。当s=1时,所有记录在同一组内排好序。

        各组内的排序通常采用直接插入法,但在这里我们尝试使用折半插入法。由于开始时s取值较大,每组中记录较少,所以排序较快。随着s的不断缩小,每组内的记录逐步增多,但由于已经按s-1排好序了,因此排序速度也比较快。

--------参考文献   熊岳山,祝恩.数据结构与算法[M].北京:清华大学出版社,2013:104.

#include<stdio.h>
#include<assert.h>

typedef int ElemType;

struct ForSort
{
	ElemType elem;
};

/*希尔插入*/
void ShellInsert(ForSort *ar, int n, int s)		//希尔插入,组内的排序采用折半插入
{	
	assert(s < n);		//规定:步长必须小于待排序的结点个数
	int i,k,r;
	ForSort temp;
	for (i = s; i < n; ++i)	//遍历
	{
		temp = ar[i];	//待插入元素
		k = i % s;		//组内的左边界
		r = i - s;		//组内的右边界
		while (k <= r)
		{
			int m = k + (r - k)/2;
			if (temp.elem < ar[m].elem)
			{
				r = m - s;
			}
			else
			{
				k = m + s;
			}
		}

		/*k为待插入结点应该插入的位置*/
		for (r = i; r > k; r -= s)
		{
			ar[r] = ar[r - s];
		}
		ar[k] = temp;
	}
}

/*希尔排序*/
void ShellSort(ForSort *ar, int n)
{
	assert(ar != NULL);
	assert(n > 0);
	for (int s = n-1; s > 0; s>>=1)
		ShellInsert(ar, n, s);
}

int main()
{
	ForSort ar[] = { 98,78,76,65,54,32,12 };
	int n = sizeof(ar) / sizeof(ForSort);
	ShellSort(ar, n);
	for (int i = 0; i < n; ++i)
	{
		printf("%-3d", ar[i].elem);
		if ((i + 1) % 5 == 0)
			printf("\n");
	}	
	return 0;
}


本程序在VS2017下运行通过

猜你喜欢

转载自blog.csdn.net/qq_41822235/article/details/80712126