NOJ--希尔排序

用cin、cout会超时
View Code
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int const ic_limit = 3000002; int iArr[ic_limit]; void vInput(int iN); void vShellSort(int iN); void vOutput(int iN); int main() { int iN; while(scanf("%d",&iN) != EOF) { memset(iArr,0,sizeof(iArr)); vInput(iN); vShellSort(iN); vOutput(iN); } return 0; } void vInput(int iN) { for(int i=1; i<=iN; i++) { scanf("%d",&iArr[i]); } } void vOutput(int iN) { printf("%d\n",iN); for(int i=1; i<iN; i++) { printf("%d ",iArr[i]); } printf("%d\n",iArr[iN]); } void vShellSort(int iN) { int i,j; int iTemp; int iDistance; iDistance = iN/2; while(iDistance >= 1) { for(i=iDistance; i<=iN; i++) { iTemp = iArr[i]; for(j=i; j>=iDistance && iTemp<iArr[j-iDistance]; j-=iDistance) { iArr[j] = iArr[j-iDistance]; } iArr[j] = iTemp; } iDistance /= 2; } }
希尔属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序
排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止
初始:d=5
49 38 65 97 76 13 27 49 55 04
49 13
|-------------------|
38 27
|-------------------|
65 49
|-------------------|
97 55
|-------------------|
76 04
|-------------------|
一趟结果:13 27 49 55 04 49 38 65 97 76
d=3
13 27 49 55 04 49 38 65 97 76
13 55 38 76
|------------|------------|------------|
27 04 65
|------------|------------|
49 49 97
|------------|------------|
二趟结果:13 04 49 38 27 49 55 65 97 76
d=1
13 04 49 38 27 49 55 65 97 76
|----|----|----|----|----|----|----|----|----|
三趟结果: 04 13 27 38 49 49 55 65 76 97
希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

浙公网安备 33010602011771号