標籤:最大值 數組 技術 最小 logs jpg 分區 image 等於
演算法的特點:
1. 有窮性。一個演算法應包含有限的操作步驟,而不能是無限的。有窮性值在合理範圍之內,如果讓電腦執行一個曆時1000年才結束的演算法,這雖然是有窮的,但超過了合理的限度,人們不把他視為有效演算法。
2. 確定性。演算法中的每一個步驟都應當是確定的,而不應當是含糊的,摩棱兩可的。演算法中的每一個步驟應當不致被解釋成不同含義的,而應是十分明確的。也就是說,演算法的含義應當是唯一的。而不應當產生歧義性。
3. 有零個或多個輸入,所謂輸入是指在執行演算法是需要從外界取得必要的資訊。
4. 有一個或多個輸出。演算法的目的是為了求解,沒有輸出的演算法是沒有意義的。
5. 有效性。演算法中的每一個步驟都應當能有效執行。並得到確定的結果。
一、快速排序演算法
快速排序是有東尼·霍爾所發展的一種排序演算法。快速排序使用分治法策略來把一個串列分為兩個子串列
演算法步驟
1. 從數列中跳出一個元素,成為"基準"
2. 重新排序數列,所有元素比基準值小的擺放在基準線前面,所有元素比基準值大的擺在後面(相同數可放在任意一邊)。在這個分區推出之後,該基準就處於數列中間的位置。這個稱為分區操作。
3. 遞迴的把小於基準值元素的子數列和大於基準值元素的子數列排序。
遞迴的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞迴下去,但是這個演算法總會退出,因為在每次迭代中,它至少會把一個元素擺到他最後的位置去。
二、堆排序演算法
堆排序是值利用堆這種資料結構所設計的一種排序演算法。堆積是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子節點的索引值或索引總是小於(或大於)它的父節點。
演算法步驟
1. 建立一個堆H[0...n-1]
2. 把堆首(最大值)和堆尾互換
3. 把堆的尺寸縮小1,並調用shift_down(0),目的是把新的數組頂端資料調整到響應位置
4. 重複步驟2,知道堆的尺寸為1
堆排序是不穩定的排序演算法,不穩定發生在堆頂元素與A[i]交換的時刻。
比如序列:{ 9, 5, 7, 5 },堆頂元素是9,堆排序下一步將9和第二個5進行交換,得到序列 { 5, 5, 7, 9 },再進行堆調整得到{ 7, 5, 5, 9 },重複之前的操作最後得到{ 5, 5, 7, 9 }從而改變了兩個5的相對次序。
三、歸併排序
歸併排序是建立在歸併操作上的一種有效排序演算法。
歸併排序的實現分為遞迴實現和非遞迴(迭代)實現。遞迴實現的歸併排序是演算法設計中分治策略的典型應用,我們將一個大問題分割成小問題分別解決。然後用所有小問題的答案來解決整個大問題。非遞迴(迭代)實現的歸併排序首先進行是兩兩歸併,然後是八八歸併,一直下去直到歸併了整個數組。
歸併排序主要依賴歸併操作。歸併操作指的是將兩個已經排序的序列合并成一個序列的操作,歸併操作步驟
1. 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合并後的序列
2. 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置
3. 比較兩個指標所指向的元素,選擇相對小的元素放入到合并空間,並移動指標到下一位置
4. 重複步驟3直到某一指標到達序列尾
5. 將另一序列剩下的所有元素直接複製到定序序列尾
四、插入排序
插入排序是一直簡單只管的排序演算法。他的工作原理非常類似我們抓撲克牌
對於末排序數組(右手抓到的牌),在已排序序列(左手已經排好序的手牌)中從後向前掃描,找到響應位置並插入。
具體步驟
1. 從第一個元素開始,該元素可以認為已經被排序
2. 取出下一個元素,在已經排序的元素序列中從後向前掃描
3. 如果該元素(已排序)大於新元素,將該元素移到下一位置
4. 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置
5. 將新元素插入到該位置後
6. 重複步驟2~5
五、插入排序的改進:二分插入排序
對於插入排序,如果比較操作的代價比交換操作大的話,可以採用二分尋找法來減少比較操作的數目,我們成為二分插入排序。
當n較大時,二分插入排序的比較次數比直接插入排序的最差情況好得多,但比直接插入排序的最好情況要差,所當以元素初始序列已經接近升序時,直接插入排序比二分插入排序比較次數少。二分插入排序元素移動次數與直接插入排序相同,依賴於元素初始序列。
首先確定目標數組的中間位置數字為45
由於45>35,所以降原數組折半並取左半子數組作為搜尋目標,左半部分的中間元素為23
由於23<35,所以再折半,選擇字數組的右半部分作為搜尋目標
而35<36,於是確定35的位置在23和36之間
六、插入排序更高效改進:希爾排序
希爾排序,也叫遞減增量排序,是插入排序的一種更高效的改進版本。希爾排序是不穩定的排序演算法。
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
1. 插入排序在對幾乎已經排好序的資料操作時,效率高,即可以達到線性排序的效率
2. 但插入排序一般來說是低效的,因為插入排序每次只能將資料移動一位
希爾排序通過將比較的全部元素分為幾個地區來提升插入排序的效能,這樣可以讓一個元素可以一次性的朝最終位置前進一大步,然後演算法再取越來越小的步長進行排序,演算法的最後一步就是普通的插入排序,但是到了這一步,需排序的資料幾乎是已經排好的了。(因此插入排序較快)
假設有一個很小的資料在一個已按升序排好序的數組的末端。如果用複雜度為O(n^2)的排序(冒泡排序或直接插入排序),可能會進行n次的比較和交換才能將該資料移至正確位置。而希爾排序會用較大的步長移動資料,所以小資料只需進行少數比較和交換即可到正確位置。
希爾排序是不穩定的排序演算法,雖然一次插入排序是穩定的,不會改變相同元素的相對順序,但在不同的插入排序過程中,相同的元素可能在各自的插入排序中移動,最後其穩定性就會被打亂。
比如序列:{ 3, 5, 10, 8, 7, 2, 8, 1, 20, 6 },h=2時分成兩個子序列 { 3, 10, 7, 8, 20 } 和 { 5, 8, 2, 1, 6 } ,未排序之前第二個子序列中的8在前面,現在對兩個子序列進行插入排序,得到 { 3, 7, 8, 10, 20 } 和 { 1, 2, 5, 6, 8 } ,即 { 3, 1, 7, 2, 8, 5, 10, 6, 20, 8 } ,兩個8的相對次序發生了改變。
七、選擇排序
選擇排序也是一種簡單直觀的排序演算法,他的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後在從剩下未排序序列中繼續尋找最小(大)元素,放到已排序序列的末尾。以此類推。
八、冒泡排序
冒泡排序是一種及其簡單的排序演算法,也是我所學的第一個排序演算法,它重複的走訪過要排序的元素,一次比較相鄰兩個元素,如果他們的順序錯誤就把他們調換過來,直到沒有元素在進行交換排序完成。
實現步驟:
1. 比較相鄰的元素,如果前一個比後一個大,就把他們兩個調換位置
2. 對每一對相鄰元素做相同的工作,從開始第一對到結尾的最後一對,這步做完後,最後的元素會是最大的數
3. 針對所有的元素重複上面步驟,除了最後一個
4. 持續每次對越來越少的元素重複上面的步驟,直到沒有數字需要比較。
九、冒泡排序的改進:雞尾酒排序
雞尾酒排序,也叫定向冒泡排序,是冒泡排序的一種改進,此演算法與冒泡排序的不同之處在於從低到高然後從高到低,而冒泡排序僅從低到高去比較序列中的每一個元素他可以得到比冒泡排序稍微好一點的效能。
以序列(2,3,4,5,1)為例,雞尾酒排序只需要訪問一次序列就可以完成排序,但如果使用冒泡排序則需要四次。但是在亂數序列的狀態下,雞尾酒排序與冒泡排序的效率都很差勁。
各排序方法效能
電腦排序演算法