排序算法的算法思想和使用場(chǎng)景總結(jié)
總結(jié)是對(duì)某一階段的工作、學(xué)習(xí)或思想中的經(jīng)驗(yàn)或情況進(jìn)行分析研究的書(shū)面材料,它能夠給人努力工作的動(dòng)力,讓我們抽出時(shí)間寫(xiě)寫(xiě)總結(jié)吧。那么總結(jié)要注意有什么內(nèi)容呢?以下是小編整理的排序算法的算法思想和使用場(chǎng)景總結(jié),僅供參考,大家一起來(lái)看看吧。
排序算法的算法思想和使用場(chǎng)景總結(jié)1
排序算法總結(jié)
所謂排序,就是要整理文件中的記錄,使之按關(guān)鍵字遞增(或遞減)次序排列起來(lái)。當(dāng)待排序記錄的關(guān)鍵字都不相同時(shí),排序結(jié)果是惟一的,否則排序結(jié)果不惟一。
在待排序的文件中,若存在多個(gè)關(guān)鍵字相同的記錄,經(jīng)過(guò)排序后這些具有相同關(guān)鍵字的記錄之間的相對(duì)次序保持不變,該排序方法是穩(wěn)定的;若具有相同關(guān)鍵字的記錄之間的相對(duì)次序發(fā)生改變,則稱這種排序方法是不穩(wěn)定的。
要注意的是,排序算法的穩(wěn)定性是針對(duì)所有輸入實(shí)例而言的。即在所有可能的輸入實(shí)例中,只要有一個(gè)實(shí)例使得算法不滿足穩(wěn)定性要求,則該排序算法就是不穩(wěn)定的。
一.插入排序
插入排序的基本思想是每步將一個(gè)待排序的記錄按其排序碼值的大小,插到前面已經(jīng)排好的文件中的適當(dāng)位置,直到全部插入完為止。插入排序方法主要有直接插入排序和希爾排序。
、.直接插入排序(穩(wěn)定)接插入排序的過(guò)程為:在插入第i個(gè)記錄時(shí),R1,R2……Ri-1已經(jīng)排好序,將第i個(gè)記錄的排序碼Ki依次和R1,R2,..,Ri-1的排序碼逐個(gè)進(jìn)行比較,找到適當(dāng)?shù)奈恢。使用直接插入排序,?duì)于具有n個(gè)記錄的文件,要進(jìn)行n-1趟排序。
代碼如下:
void Dir_Insert(int A[],int N) //直接插入排序{ int j,t;for(int i=1;it) { A[j+1]=A[j];j--;} A[j+1]=t;} }
1 ②.希爾排序(不穩(wěn)定):
希爾(Shell)排序的基本思想是:先取一個(gè)小于n的整數(shù)d1作為第一個(gè)增量把文件的全部記錄分成d1個(gè)組。所有距離為d1的倍數(shù)的記錄放在同一個(gè)組中。先在各組內(nèi)進(jìn)行直接插入排序;然后,取得第二個(gè)增量d2 一般取d1=n/2,di+1=di/2。如果結(jié)果為偶數(shù),則加1,保證di為奇數(shù)。 希爾排序是不穩(wěn)定的,希爾排序的執(zhí)行時(shí)間依賴于增量序列,其平均時(shí)間復(fù)雜度為O(n^). 代碼如下: void Shell(int A[],int n) //Shell排序{ int i,j,k,t;(n/2)%2 == 0 ? k = n/2+1:k = n/2;//保證增量為奇數(shù) while(k > 0) { for(j=k;j=0 && A[i]>t) { A[i+k]=A[i];i=i-k;} A[i+k]=t;} if(k == 1) break;(k/2)%2 ==0 ? k=k/2+1:k=k/2;} } 二.選擇排序 選擇排序的基本思想是每步從待排序的記錄中選出排序碼最小的記錄,順序存放在已排序的記錄序列的后面,直到全部排完。選擇排序中主要使用直接選擇排序和堆排 2序。 、.直接選擇排序(不穩(wěn)定) 直接選擇排序的過(guò)程是:首先在所有記錄中選出序碼最小的記錄,把它與第1個(gè)記錄交換,然后在其余的記錄內(nèi)選出排序碼最小的記錄,與第2個(gè)記錄交換......依次類推,直到所有記錄排完為止。 無(wú)論文件初始狀態(tài)如何,在第i趟排序中選出最小關(guān)鍵字的記錄,需要做n-i次比較,因此,總的比較次數(shù)為n(n-1)/2=O(n^2)。當(dāng)初始文件為正序時(shí),移動(dòng)次數(shù)為0;文件初態(tài)為反序時(shí),每趟排序均要執(zhí)行交換操作,總的移動(dòng)次數(shù)取最大值3(n-1)。直接選擇排序的平均時(shí)間復(fù)雜度為O(n^2)。直接選擇排序是不穩(wěn)定的。 代碼如下: void Dir_Choose(int A[],int n) //直接選擇排序{ int k,t;for(int i=0;i ②.堆排序(不穩(wěn)定) 堆排序是一種樹(shù)形選擇排序,是對(duì)直接選擇排序的有效改進(jìn)。n個(gè)關(guān)鍵字序列K1,K2,.……,Kn稱為堆,當(dāng)且僅當(dāng)該序列滿足(Ki<=K2i且Ki<=k2i+1)或(ki>=K2i且Ki>=K2i+1),(1<=i<=n/2)。根結(jié)點(diǎn)(堆頂)的關(guān)鍵字是堆里所有結(jié)點(diǎn)關(guān)鍵字中最小者,稱為小根堆;根結(jié)點(diǎn)的關(guān)鍵字是堆里所有結(jié)點(diǎn)關(guān)鍵字中最大者,稱為大根堆。 3若將此序列所存儲(chǔ)的向量R[1..n]看作是一棵完全二叉樹(shù)的存儲(chǔ)結(jié)構(gòu),則堆實(shí)質(zhì)上是滿足如下性質(zhì)的完全二叉樹(shù):樹(shù)中任一非葉結(jié)點(diǎn)的關(guān)鍵字均不大于(或不小于)其左右孩子(若存在)結(jié)點(diǎn)的關(guān)鍵字。 堆排序的關(guān)鍵步驟有兩個(gè):一是如何建立初始堆;二是當(dāng)堆的根結(jié)點(diǎn)與堆的最后一個(gè)結(jié)點(diǎn)交換后,如何對(duì)少了一個(gè)結(jié)點(diǎn)后的結(jié)點(diǎn)序列做調(diào)整,使之重新成為堆。堆排序的最壞時(shí)間復(fù)雜度為O(nlog2n),堆排序的平均性能較接近于最壞性能。由于建初始堆所需的比較次數(shù)較多,所以堆排序不適宜于記錄較少的文件。堆排序是就地排序,輔助空間為O(1),它是不穩(wěn)定的排序方法。 代碼略.. 三.交換排序 交換排序的基本思想是:兩兩比較待排序記錄的排序碼,并交換不滿足順序要求的那寫(xiě)偶對(duì),直到滿足條件為止。交換排序的主要方法有冒泡排序和快速排序. 、.冒泡排序(穩(wěn)定的) 冒泡排序?qū)⒈慌判虻挠涗洈?shù)組R[1……n]垂直排列,每個(gè)記錄R[i]看作是重量為ki的氣泡。根據(jù)輕氣泡不能在重氣泡之下的原則,從下往上掃描數(shù)組R;凡掃描到違反本原則的輕氣泡,就使其向上"漂浮"。如此反復(fù)進(jìn)行,直到最后任何兩個(gè)氣泡都是輕者在上,重者在下為止。 冒泡排序的具體過(guò)程如下: 第一步,先比較k1和k2,若k1>k2,則交換k1和k2所在的`記錄,否則不交換。繼續(xù)對(duì)k2和k3重復(fù)上述過(guò)程,直到處理完kn-1和kn。這時(shí)最大的排序碼記錄轉(zhuǎn)到了最后位置,稱第1次起泡,共執(zhí)行n-1次比較。 與第一步類似,從k1和k2開(kāi)始比較,到kn-2和kn-1為止,共執(zhí)行n-2次比較。 依次類推,共做n-1次起泡,完成整個(gè)排序過(guò)程。 若文件的初始狀態(tài)是正序的,一趟掃描即可完成排序。所需關(guān)鍵字比較次數(shù)為n-1次,記錄移動(dòng)次數(shù)為0。因此,冒泡排序最好的時(shí)間復(fù)雜度為O(n)。 若初始文件是反序的,需要進(jìn)行n-1趟排序。每趟排序要進(jìn)行n-i次關(guān)鍵字的比較(1<=i<=n-1),且每次比較都必須移動(dòng)記錄三次來(lái)達(dá)到交換記錄位置。在這種情況下,比較次數(shù)達(dá)到最大值n(n-1)/2=O(n^2),移動(dòng)次數(shù)也達(dá)到最大值3n(n-1)/2=O(n^2)。因此,冒泡排序的最壞時(shí)間復(fù)雜度為O(n^2)。 雖然冒泡排序不一定要進(jìn)行n-1趟,但由于它的記錄移動(dòng)次數(shù)較多,故平均性能比直接插入排序要差得多。冒泡排序是就地排序,且它是穩(wěn)定的。 代碼如下: 4 void QP(int A[],int n) //優(yōu)化的冒泡排序 { int count=0,t,flag;for(int i=0;i ②.快速排序:(不穩(wěn)定的) 快速排序采用了一種分治的策略,通常稱其為分治法,其基本思想是:將原問(wèn)題分解為若干個(gè)規(guī)模更小但結(jié)構(gòu)與原問(wèn)題相似的子問(wèn)題。遞歸地解這些子問(wèn)題,然后將這些子問(wèn)題的解組合為原問(wèn)題的解。 快速排序的具體過(guò)程如下: 第一步,在待排序的n個(gè)記錄中任取一個(gè)記錄,以該記錄的排序碼為準(zhǔn),將所有記錄分成兩組,第1組各記錄的排序碼都小于等于該排序碼,第2組各記錄的排序碼都大于該排序碼,并把該記錄排在這兩組中間。 第二步,采用同樣的方法,對(duì)左邊的組和右邊的組進(jìn)行排序,直到所有記錄都排到相應(yīng)的位置為止。 代碼如下: void Quick_Sort(int A[],int low,int high) //low和high是數(shù)組的下標(biāo){ if(low 5 { int temp,t=A[low];int l=low,h=high;while(l 四.歸并排序 歸并排序是將兩個(gè)或兩個(gè)以上的有序子表合并成一個(gè)新的有序表。初始時(shí),把含有n個(gè)結(jié)點(diǎn)的待排序序列看作由n個(gè)長(zhǎng)度都為1的有序子表組成,將它們依次兩兩歸并得到長(zhǎng)度為2的若干有序子表,再對(duì)它們兩兩合并。直到得到長(zhǎng)度為n的有序表,排序結(jié)束。 歸并排序是一種穩(wěn)定的排序,可用順序存儲(chǔ)結(jié)構(gòu),也易于在鏈表上實(shí)現(xiàn),對(duì)長(zhǎng)度為n的文件,需進(jìn)行l(wèi)og2n趟二路歸并,每趟歸并的時(shí)間為O(n),故其時(shí)間復(fù)雜度無(wú)論是在最好情況下還是在最壞情況下均是O(nlog2n)。歸并排序需要一個(gè)輔助向量來(lái)暫存兩個(gè)有序子文件歸并的結(jié)果,故其輔助空間復(fù)雜度為O(n),顯然它不是就地排序。 代碼略... 五.基數(shù)排序 設(shè)單關(guān)鍵字的每個(gè)分量的取值范圍均是C0<=Kj<=Crd-1(0<=j<=rd),可能的取值個(gè)數(shù)rd稱為基數(shù).基數(shù)的選擇和關(guān)鍵字的分解因關(guān)鍵字的類型而異. (1).若關(guān)鍵字是十進(jìn)制整數(shù),則按個(gè)、十等位進(jìn)行分解,基數(shù)rd=10,C0=0,C9=9,d為最長(zhǎng)整數(shù)的位數(shù). (2).若關(guān)鍵字是小寫(xiě)的英文字符串,則rd=26,C0='a',C25='z',d為最長(zhǎng)字符串的長(zhǎng)度. 基數(shù)排序的基本思想是:從低位到高位依次對(duì)待排序的關(guān)鍵碼進(jìn)行分配和收集,經(jīng)過(guò)d趟分配和收集,就可以得到一個(gè)有序序列. 按平均時(shí)間將排序分為四類: 。1)平方階(O(n2))排序 一般稱為簡(jiǎn)單排序,例如直接插入、直接選擇和冒泡排序; 。2)線性對(duì)數(shù)階(O(nlgn))排序 如快速、堆和歸并排序; 。3)O(n1+£)階排序 £是介于0和1之間的常數(shù),即0<£<1,如希爾排序; 。4)線性階(O(n))排序 如基數(shù)排序。 各種排序方法比較 簡(jiǎn)單排序中直接插入最好,快速排序最快,當(dāng)文件為正序時(shí),直接插入和冒泡均最佳。 影響排序效果的因素 因?yàn)椴煌呐判蚍椒ㄟm應(yīng)不同的應(yīng)用環(huán)境和要求,所以選擇合適的排序方法應(yīng)綜合考慮下列因素: 、俅判虻挠涗洈(shù)目n; 、谟涗浀拇笮(規(guī)模); 、坳P(guān)鍵字的結(jié)構(gòu)及其初始狀態(tài); 、軐(duì)穩(wěn)定性的要求; 、菡Z(yǔ)言工具的條件; ⑥存儲(chǔ)結(jié)構(gòu); ⑦時(shí)間和輔助空間復(fù)雜度等。 不同條件下,排序方法的選擇 7 (1)若n較小(如n≤50),可采用直接插入或直接選擇排序。 當(dāng)記錄規(guī)模較小時(shí),直接插入排序較好;否則因?yàn)橹苯舆x擇移動(dòng)的記錄數(shù)少于直接插人,應(yīng)選直接選擇排序?yàn)橐恕?/p> (2)若文件初始狀態(tài)基本有序(指正序),則應(yīng)選用直接插人、冒泡或隨機(jī)的快速排序?yàn)橐耍?/p> (3)若n較大,則應(yīng)采用時(shí)間復(fù)雜度為O(nlgn)的排序方法:快速排序、堆排序或歸并排序。 快速排序是目前基于比較的內(nèi)部排序中被認(rèn)為是最好的方法,當(dāng)待排序的關(guān)鍵字是隨機(jī)分布時(shí),快速排序的平均時(shí)間最短; 堆排序所需的輔助空間少于快速排序,并且不會(huì)出現(xiàn)快速排序可能出現(xiàn)的最壞情況。這兩種排序都是不穩(wěn)定的。 若要求排序穩(wěn)定,則可選用歸并排序。但從單個(gè)記錄起進(jìn)行兩兩歸并的排序算法并不值得提倡,通?梢詫⑺椭苯硬迦肱判蚪Y(jié)合在一起使用。先利用直接插入排序求得較長(zhǎng)的有序子文件,然后再兩兩歸并之。因?yàn)橹苯硬迦肱判蚴欠(wěn)定的,所以改進(jìn)后的歸并排序仍是穩(wěn)定的。 一、冒泡排序 已知一組無(wú)序數(shù)據(jù)a[1]、a[2]、……a[n],需將其按升序排列。首先比較a[1]與a[2]的值,若a[1]大于a[2]則交換兩者的值,否則不變。再比較a[2]與a[3]的值,若a[2]大于a[3]則交換兩者的值,否則不變。再比較a[3]與a[4],以此類推,最后比較a[n-1]與a[n]的值。這樣處理一輪后,a[n]的值一定是這組數(shù)據(jù)中最大的。再對(duì)a[1]~a[n- 1]以相同方法處理一輪,則a[n-1]的值一定是a[1]~a[n-1]中最大的。再對(duì)a[1]~a[n-2]以相同方法處理一輪,以此類推。共處理n-1輪后a[1]、a[2]、……a[n]就以升序排列了。 優(yōu)點(diǎn):穩(wěn)定; 缺點(diǎn):慢,每次只能移動(dòng)相鄰兩個(gè)數(shù)據(jù)。 二、選擇排序 每一趟從待排序的數(shù)據(jù)元素中選出最。ɑ蜃畲螅┑囊粋(gè)元素,順序放在已排好序的數(shù)列的最后,直到全部待排序的數(shù)據(jù)元素排完。 選擇排序是不穩(wěn)定的排序方法。 n個(gè)記錄的文件的直接選擇排序可經(jīng)過(guò)n-1趟直接選擇排序得到有序結(jié)果: ①初始狀態(tài):無(wú)序區(qū)為R[1..n],有序區(qū)為空。 、诘1趟排序 在無(wú)序區(qū)R[1..n]中選出關(guān)鍵字最小的記錄R[k],將它與無(wú)序區(qū)的第1個(gè)記錄R[1]交換,使R[1..1]和R[2..n]分別變?yōu)橛涗泜(gè)數(shù)增加1個(gè)的新有序區(qū)和記錄個(gè)數(shù)減少1個(gè)的'新無(wú)序區(qū)。 …… 、鄣趇趟排序 第i趟排序開(kāi)始時(shí),當(dāng)前有序區(qū)和無(wú)序區(qū)分別為R[1..i-1]和R(1≤i≤n-1)。該趟排序從當(dāng)前無(wú)序區(qū)中選出關(guān)鍵字最小的記錄R[k],將它與無(wú)序區(qū)的第1個(gè)記錄R交換,使R[1……i]和R分別變?yōu)橛涗泜(gè)數(shù)增加1個(gè)的新有序區(qū)和記錄個(gè)數(shù)減少1個(gè)的新無(wú)序區(qū)。 這樣,n個(gè)記錄的文件的直接選擇排序可經(jīng)過(guò)n-1趟直接選擇排序得到有序結(jié)果。 優(yōu)點(diǎn):移動(dòng)數(shù)據(jù)的次數(shù)已知(n-1次); 缺點(diǎn):比較次數(shù)多。 三、插入排序 已知一組升序排列數(shù)據(jù)a[1]、a[2]、……a[n],一組無(wú)序數(shù)據(jù)b[1]、 b[2]、……b[m],需將二者合并成一個(gè)升序數(shù)列。首先比較b[1]與a[1]的值,若b[1]大于a[1],則跳過(guò),比較b[1]與a[2]的值,若b[1]仍然大于a[2],則繼續(xù)跳過(guò),直到b[1]小于a數(shù)組中某一數(shù)據(jù)a[x],則將a[x]~a[n]分別向后移動(dòng)一位,將b[1]插入到原來(lái)a[x]的位置這就完成了b[1]的插入。b[2]~b[m]用相同方法插入。(若無(wú)數(shù)組a,可將b[1]當(dāng)作n=1的數(shù)組a) 優(yōu)點(diǎn):穩(wěn)定,快; 缺點(diǎn):比較次數(shù)不一定,比較次數(shù)越少,插入點(diǎn)后的數(shù)據(jù)移動(dòng)越多,特別是當(dāng)數(shù)據(jù)總量龐大的時(shí)候,但用鏈表可以解決這個(gè)問(wèn)題。 四、縮小增量排序 由希爾在1959年提出,又稱希爾排序(shell排序)。 已知一組無(wú)序數(shù)據(jù)a[1]、a[2]、……a[n],需將其按升序排列。發(fā)現(xiàn)當(dāng)n不大時(shí),插入排序的效果很好。首先取一增量d(d 優(yōu)點(diǎn):快,數(shù)據(jù)移動(dòng)少; 缺點(diǎn):不穩(wěn)定,d的取值是多少,應(yīng)取多少個(gè)不同的值,都無(wú)法確切知道,只能憑經(jīng)驗(yàn)來(lái)取。 五、快速排序 快速排序是冒泡排序的改進(jìn)版,是目前已知的最快的排序方法。 已知一組無(wú)序數(shù)據(jù)a[1]、a[2]、……a[n],需將其按升序排列。首先任取數(shù)據(jù)a[x]作為基準(zhǔn)。比較a[x]與其它數(shù)據(jù)并排序,使a[x]排在數(shù)據(jù)的第k位,并且使a[1]~a[k-1]中的每一個(gè)數(shù)據(jù)a[x],然后采用分治的策略分別對(duì)a[1]~a[k-1]和a[k+1]~a[n]兩組數(shù)據(jù)進(jìn)行快速排序。 優(yōu)點(diǎn):極快,數(shù)據(jù)移動(dòng)少; 缺點(diǎn):不穩(wěn)定。 六、箱排序 已知一組無(wú)序正整數(shù)數(shù)據(jù)a[1]、a[2]、……a[n],需將其按升序排列。首先定義一個(gè)數(shù)組x[m],且m>=a[1]、a[2]、……a[n],接著循環(huán)n次,每次x[a]++。 優(yōu)點(diǎn):快,效率達(dá)到O(1)缺點(diǎn):數(shù)據(jù)范圍必須為正整數(shù)并且比較小 七、歸并排序 歸并排序是多次將兩個(gè)或兩個(gè)以上的有序表合并成一個(gè)新的有序表。最簡(jiǎn)單的歸并是直接將兩個(gè)有序的子表合并成一個(gè)有序的表。 歸并排序是穩(wěn)定的排序.即相等的元素的順序不會(huì)改變.如輸入記錄1(1) 3(2) 2(3) 2(4) 5(5) (括號(hào)中是記錄的關(guān)鍵字)時(shí)輸出的1(1) 2(3) 2(4) 3(2) 5(5)中的2和2是按輸入的順序。這對(duì)要排序數(shù)據(jù)包含多個(gè)信息而要按其中的某一個(gè)信息排序,要求其它信息盡量按輸入的順序排列時(shí)很重要.這也是它比快速排序優(yōu)勢(shì)的地方. 歸并排序:歸并排序是一種非就地排序,將需要與待排序序列一樣多的輔助空間。在使用它對(duì)兩個(gè)己有序的序列歸并,將有無(wú)比的優(yōu)勢(shì)。其時(shí)間復(fù)雜度無(wú)論是在最好情況下還是在最壞情況下均是O(nlog2n)。對(duì)數(shù)據(jù)的有序性不敏感。若數(shù)據(jù)節(jié)點(diǎn)數(shù)據(jù)量大,那將不適合。但可改造成索引操作,效果將非常出色。 堆排序:由于它在直接選擇排序的基礎(chǔ)上利用了比較結(jié)果形成。效率提高很大。它完成排序的總比較次數(shù)為O(nlog2n)。它是對(duì)數(shù)據(jù)的有序性不敏感的一種算法。但堆排序?qū)⑿枰鰞蓚(gè)步驟:-是建堆,二是排序(調(diào)整堆)。所以一般在小規(guī)模的序列中不合適,但對(duì)于較大的序列,將表現(xiàn)出優(yōu)越的性能。 1. 概述 排序算法是計(jì)算機(jī)技術(shù)中最基本的算法,許多復(fù)雜算法都會(huì)用到排序。盡管各種排序算法都已被封裝成庫(kù)函數(shù)供程序員使用,但了解排序算法的思想和原理,對(duì)于編寫(xiě)高質(zhì)量的軟件,顯得非常重要。 本文介紹了常見(jiàn)的排序算法,從算法思想,復(fù)雜度和使用場(chǎng)景等方面做了總結(jié)。 2. 幾個(gè)概念 。1)排序穩(wěn)定:如果兩個(gè)數(shù)相同,對(duì)他們進(jìn)行的排序結(jié)果為他們的相對(duì)順序不變。例如A={1,2,1,2,1}這里排序之后是A = {1,1,1,2,2} 穩(wěn)定就是排序后第一個(gè)1就是排序前的第一個(gè)1,第二個(gè)1就是排序前第二個(gè)1,第三個(gè)1就是排序前的第三個(gè)1。同理2也是一樣。不穩(wěn)定就是他們的順序與開(kāi)始順序不一致。 。2)原地排序:指不申請(qǐng)多余的空間進(jìn)行的排序,就是在原來(lái)的排序數(shù)據(jù)中比較和交換的排序。例如快速排序,堆排序等都是原地排序,合并排序,計(jì)數(shù)排序等不是原地排序。 總體上說(shuō),排序算法有兩種設(shè)計(jì)思路,一種是基于比較,另一種不是基于比較。《算法導(dǎo)論》一書(shū)給出了這樣一個(gè)證明:“基于比較的算法的最優(yōu)時(shí)間復(fù)雜度是O(N lg N)”。對(duì)于基于比較的算法,有三種設(shè)計(jì)思路,分別為:插入排序,交換排序和選擇排序。非基于比較的`排序算法時(shí)間復(fù)雜度為O(lg N),之所以復(fù)雜度如此低,是因?yàn)樗鼈円话銓?duì)排序數(shù)據(jù)有特殊要求。如計(jì)數(shù)排序要求數(shù)據(jù)范圍不會(huì)太大,基數(shù)排序要求數(shù)據(jù)可以分解成多個(gè)屬性等。 3. 基于比較的排序算法 正如前一節(jié)介紹的,基于比較的排序算法有三種設(shè)計(jì)思路,分別為插入,交換和選擇。對(duì)于插入排序,主要有直接插入排序,希爾排序;對(duì)于交換排序,主要有冒泡排序,快速排序;對(duì)于選擇排序,主要有簡(jiǎn)單選擇排序,堆排序;其它排序:歸并排序。 3.1 插入排序 (1) 直接插入排序 特點(diǎn):穩(wěn)定排序,原地排序,時(shí)間復(fù)雜度O(N*N) 思想:將所有待排序數(shù)據(jù)分成兩個(gè)序列,一個(gè)是有序序列S,另一個(gè)是待排序序列U,初始時(shí),S為空,U為所有數(shù)據(jù)組成的數(shù)列,然后依次將U中的數(shù)據(jù)插到有序序列S中,直到U變?yōu)榭铡?/p> 適用場(chǎng)景:當(dāng)數(shù)據(jù)已經(jīng)基本有序時(shí),采用插入排序可以明顯減少數(shù)據(jù)交換和數(shù)據(jù)移動(dòng)次數(shù),進(jìn)而提升排序效率。 (2)希爾排序 特點(diǎn):非穩(wěn)定排序,原地排序,時(shí)間復(fù)雜度O(n^lamda)(1 < lamda < 2), lamda和每次步長(zhǎng)選擇有關(guān)。 思想:增量縮小排序。先將序列按增量劃分為元素個(gè)數(shù)近似的若干組,使用直接插入排序法對(duì)每組進(jìn)行排序,然后不斷縮小增量直至為1,最后使用直接插入排序完成排序。 適用場(chǎng)景:因?yàn)樵隽砍跏贾挡蝗菀走x擇,所以該算法不常用。 3.2 交換排序 。1)冒泡排序 特點(diǎn):穩(wěn)定排序,原地排序,時(shí)間復(fù)雜度O(N*N) 思想:將整個(gè)序列分為無(wú)序和有序兩個(gè)子序列,不斷通過(guò)交換較大元素至無(wú)序子序列首完成排序。 適用場(chǎng)景:同直接插入排序類似 。2)快速排序 特點(diǎn):不穩(wěn)定排序,原地排序,時(shí)間復(fù)雜度O(N*lg N) 思想:不斷尋找一個(gè)序列的樞軸點(diǎn),然后分別把小于和大于樞軸點(diǎn)的數(shù)據(jù)移到樞軸點(diǎn)兩邊,然后在兩邊數(shù)列中繼續(xù)這樣的操作,直至全部序列排序完成。 適用場(chǎng)景:應(yīng)用很廣泛,差不多各種語(yǔ)言均提供了快排API 3.3 選擇排序 。1)簡(jiǎn)單選擇排序 特點(diǎn):不穩(wěn)定排序(比如對(duì)3 3 2三個(gè)數(shù)進(jìn)行排序,第一個(gè)3會(huì)與2交換),原地排序,時(shí)間復(fù)雜度O(N*N) 思想:將序列劃分為無(wú)序和有序兩個(gè)子序列,尋找無(wú)序序列中的最。ù螅┲岛蜔o(wú)序序列的首元素交換,有序區(qū)擴(kuò)大一個(gè),循環(huán)下去,最終完成全部排序。 適用場(chǎng)景:交換少 (2) 堆排序 特點(diǎn):非穩(wěn)定排序,原地排序,時(shí)間復(fù)雜度O(N*lg N) 思想:小頂堆或者大頂堆 適用場(chǎng)景:不如快排廣泛 3.4 其它排序 。1) 歸并排序 特點(diǎn):穩(wěn)定排序,非原地排序,時(shí)間復(fù)雜度O(N*N) 思想:首先,將整個(gè)序列(共N個(gè)元素)看成N個(gè)有序子序列,然后依次合并相鄰的兩個(gè)子序列,這樣一直下去,直至變成一個(gè)整體有序的序列。 適用場(chǎng)景:外部排序 4. 非基于比較的排序算法 非基于比較的排序算法主要有三種,分別為:基數(shù)排序,桶排序和計(jì)數(shù)排序。這些算法均是針對(duì)特殊數(shù)據(jù)的,不如要求數(shù)據(jù)分布均勻,數(shù)據(jù)偏差不會(huì)太大。采用的思想均是內(nèi)存換時(shí)間,因而全是非原地排序。 4.1 基數(shù)排序 特點(diǎn):穩(wěn)定排序,非原地排序,時(shí)間復(fù)雜度O(N) 思想:把每個(gè)數(shù)據(jù)看成d個(gè)屬性組成,依次按照d個(gè)屬性對(duì)數(shù)據(jù)排序(每輪排序可采用計(jì)數(shù)排序),復(fù)雜度為O(d*N) 適用場(chǎng)景:數(shù)據(jù)明顯有幾個(gè)關(guān)鍵字或者幾個(gè)屬性組成 4.2 桶排序 特點(diǎn):穩(wěn)定排序,非原地排序,時(shí)間復(fù)雜度O(N) 思想:將數(shù)據(jù)按大小分到若干個(gè)桶(比如鏈表)里面,每個(gè)桶內(nèi)部采用簡(jiǎn)單排序算法進(jìn)行排序。 適用場(chǎng)景:0 4.3 計(jì)數(shù)排序 特點(diǎn):穩(wěn)定排序,非原地排序,時(shí)間復(fù)雜度O(N) 思想:對(duì)每個(gè)數(shù)據(jù)出現(xiàn)次數(shù)進(jìn)行技術(shù)(用hash方法計(jì)數(shù),最簡(jiǎn)單的hash是數(shù)組。缓髲拇蟮叫』蛘邚男〉酱筝敵雒總(gè)數(shù)據(jù)。 使用場(chǎng)景:比基數(shù)排序和桶排序廣泛得多。 5. 總結(jié) 對(duì)于基于比較的排序算法,大部分簡(jiǎn)單排序(直接插入排序,選擇排序和冒泡排序)都是穩(wěn)定排序,選擇排序除外;大部分高級(jí)排序(除簡(jiǎn)單排序以外的)都是不穩(wěn)定排序,歸并排序除外,但歸并排序需要額外的存儲(chǔ)空間。對(duì)于非基于比較的排序算法,它們都對(duì)數(shù)據(jù)規(guī)律有特殊要求 ,且采用了內(nèi)存換時(shí)間的思想。排序算法如此之多,往往需要根據(jù)實(shí)際應(yīng)用選擇最適合的排序算法。 【排序算法的算法思想和使用場(chǎng)景總結(jié)】相關(guān)文章: 關(guān)于kmeans算法報(bào)告總結(jié)05-09 績(jī)效工資的算法01-14 失業(yè)保險(xiǎn)的算法06-20 年假加班工資的算法01-14 曠工扣工資的算法01-23 《乘法的結(jié)合律和簡(jiǎn)便算法》 教學(xué)設(shè)計(jì)04-13排序算法的算法思想和使用場(chǎng)景總結(jié)2
排序算法的算法思想和使用場(chǎng)景總結(jié)3