希尔排序

先取一个正整数(分组步长)d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止。

希尔排序_第1张图片

算法思想:
在直接插入排序算法中,每次插入一个数,使有序序列只增加1个节点,并且对插入下一个数没有提供任何帮助。如果比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。

希尔排序是不稳定的。

code1

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

#define A 11
int s[A]={592,401,874,141,348,72,911,887,820,283,100};

void shellsort(int s[],int d,int n)
{
	int i,j,temp;

	for(i=d;i<n;i++)					//从每一组的第二个元素开始插入排序
	{
		temp=s[i];
		j=i-d;
		while(j>=0 && s[j]>temp)		//寻找插入位置,后移
		{
			s[j+d]=s[j];
			j-=d;
		}
		s[j+d]=temp;					//插入
	}
	return;
}

int main(void)
{
	int d,i;

	d=A/2;								//步长
	while(d>=1)
	{
		shellsort(s,d,A);				//针对每个步长进行插入排序
		d=d/2;
	}
	printf("The shell sort result is:\n");
	for(i=0;i<A;i++)
	{
		printf("%d ",s[i]);
	}
	printf("\n");

	system("pause");
	return 0;
}

code2(foolish)

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

#define A 11
int s[A]={592,401,874,141,348,72,911,887,820,283,100};

void shellsort(int s[],int n,int d)
{
	int i,j,k;
	int cnt;
	int temp[A];
	int num;

	for(i=0;i<d;i++)
	{
		cnt=0;
		while(cnt*d+i<n)
		{
			num=s[cnt*d+i];
			j=0;
			while(num>temp[j] && j<cnt)
			{
				j++;
			}
			if(j<cnt)
			{
				k=cnt;
				while(k>j)
				{
					temp[k]=temp[k-1];
					k--;
				}
				temp[j]=num;
				cnt++;
			}
			else
			{
				temp[cnt++]=num;
			}

			for(k=0;k<cnt;k++)
			{
				s[k*d+i]=temp[k];
			}
		}
	}
	return;
}

int main(void)
{
	int d;
	int i;
	
	d=A/2;
	while(d>=1)
	{
		shellsort(s,A,d);
		d=d/2;
	}

	printf("The shell sort result is:\n");
	for(i=0;i<A;i++)
	{
		printf("%d ",s[i]);
	}
	printf("\n");

	system("pause");
	return 0;
}


你可能感兴趣的:(希尔排序)