c語言實現希爾排序
阿新 • • 發佈:2018-12-23
自己看書時,對希爾排序的理解一直處於茫然狀態,然後在維基百科上看到了這樣一句話,再加上這樣一個例子,總算消除了我的迷惑。
因為訪問危機百科需要翻牆,故複製了了相關內容在本部落格裡,若讀者已翻牆,可以直接點此進入維基百科檢視。
--------------------------------------以下內容來源於維基百科--------------------------------------
一個更好理解的希爾排序實現:將陣列列在一個表中並對列排序(用插入排序)。重複這過程,不過每次用更長的列來進行。最後整個表就只有一列了。將陣列轉換至表是為了更好地理解這演算法,演算法本身僅僅對原陣列進行排序(通過增加索引的步長,例如是用
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);
}
}
執行截圖: