希爾排序演算法是突破這個時間負責度(o(n
2n^2
n2))的第一批演算法之一。之前的直接插入排序,應該說,它的效率在某些時候是很高的,比如,我們的記錄本身就是基本有序的,我們只需要少量的插入操作,就可以完成整個記錄集的排序工作,此時直接插入很高效。還有就是記錄數比較少時,直接插入的優勢也比較明顯。問題在於,兩個條件本身就過於苛刻。現實中記錄少或者基本有序都屬於特殊情況。
如何讓待排序的記錄個數較少呢?很容易想到就是將原來的大量記錄數的記錄進行分組。分割成若干個子串行,此時每個子串行待排序的記錄個數就比較少了。然後在這些子串行內分別進行直接插入操作,當整個序列基本有序時,注意只是基本有序時,再對全體記錄進行一次直接插入排序。
我們分割待排序記錄的目的是減少待排序記錄的個數,並且使整個序列向基本有序發展。因此,我們需要採取跳躍分割的策略:將相距某個"增量"的記錄組成乙個子串行,這樣才能保證在子串行內分別進行直接插入排序後得到的結果是基本有序
而不是區域性有序**。
/* 對順序表l作希爾排序*/
#include
#define maxsize 10
typedef
struct
sqlist;
void
swap
(sqlist *l,
int i,
int j)
void
shellsort
(sqlist *l)
l->r[j+increment]
= l->r[0]
;//插入}}
}while
(increment >1)
;}intmain()
shellsort
(&h)
;for
(int i =
1; i < n; i++)}
/*------------------
程式執行示例:
100 9 1 5 8 3 7 4 6 2
1 2 3 4 5 6 7 8 9 %
------------------
*/
希爾排序的關鍵並不是隨便分組後各自排序,而是將相隔某個"增量"的記錄組成乙個子串行,實現跳躍式的移動,使得排序的效率提高。
這裡的增量的選取非常的關鍵,**中increment=increment/3+1;的方式選取增量的,可究竟應該選取什麼樣的增量才是最好,目前還是乙個數學難題,迄今為止沒有找到乙個最好的增量排序。不過大量的研究表明,當增量序列為dlta[k] = 2t−
k+1−
12^-1
2t−k+1
−1時,可以獲得不錯的效果,其時間複雜度為o(n32
n^}n2
3)要好於直接排序的o(n
2n^2
n2)。其中需要注意的是,增量序列的最後乙個增量值必須等於1才行。另外由於記錄是跳躍式的移動,希爾排序並不是穩定的排序演算法。
P1732 活蹦亂跳的香穗子
香穗子在田野上調蘑菇 她跳啊跳,發現自己很無聊,於是她想了乙個有趣的事情,每個格仔最多只能經過1次,且每個格仔都有其價值 跳的規則是這樣的,香穗子可以向上下左右四個方向跳到相鄰的格仔,並且她只能往價值更高 這裡是嚴格的大於 的格仔跳.香穗子可以從任意的格仔出發,在任意的格仔結束,那麼她最多能跳幾次?...
記憶化搜尋 活蹦亂跳的香穗子
活蹦亂跳的香穗子 香穗子在田野上調蘑菇 她跳啊跳,發現自己很無聊,於是她想了乙個有趣的事情,每個格仔最多只能經過1次,且每個格仔都有其價值 跳的規則是這樣的,香穗子可以向上下左右四個方向跳到相鄰的格仔,並且她只能往價值更高 這裡是嚴格的大於 的格仔跳.香穗子可以從任意的格仔出發,在任意的格仔結束,那...
洛谷p1732 活蹦亂跳的香穗子 二維DP
今天不bb了,直接帖原題吧 位址 香穗子在田野上調蘑菇 她跳啊跳,發現自己很無聊,於是她想了乙個有趣的事情,每個格仔最多只能經過1次,且每個格仔都有其價值 跳的規則是這樣的,香穗子可以向上下左右四個方向跳到相鄰的格仔,並且她只能往價值更高 這裡是嚴格的大於 的格仔跳.香穗子可以從任意的格仔出發,在任...