當前位置:首頁 » 操作系統 » 排序演算法8

排序演算法8

發布時間: 2023-07-07 01:09:06

❶ 常見排序演算法歸納

排序演算法一般分類:

比較兩個相鄰的元素,將值大的元素交換至右端。

依次比較兩個相鄰的數,將小數放到前面,大數放到後面

即在第一趟:首先比較第1個數和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此一直繼續下去,直到比較最後兩個數,將小數放前,大數放後。然後重復第一趟步驟,直到所有排序完成。

第一趟比較完成後,最後一個數一定是數組中最大的一個數,所以第二趟比較的時候最後一個數不參與比較。

第二趟完成後,倒數第二個數也一定是數組中第二大的數,所以第三趟比較的時候最後兩個數不參與比較。

依次類推......

輸出結果:

冒泡排序的優點: 每進行一趟排序,就會少比較一次,因為每進行一趟排序都會找出一個較大值。如上例:第一趟比較之後,排在最後的一個數一定是最大的一個數,第二趟排序的時候,只需要比較除了最後一個數以外的其他的數,同樣也能找出一個最大的數排在參與第二趟比較的數後面,第三趟比較的時候,只需要比較除了最後兩個數以外的其他的數,以此類推……也就是說,沒進行一趟比較,每一趟少比較一次,一定程度上減少了演算法的量。

用時間復雜度來說:

從一個數組中隨機選出一個數N,通過一趟排序將數組分割成三個部分,1、小於N的區域 2、等於N的區域 3、大於N的區域,然後再按照此方法對小於區的和大於區分別遞歸進行,從而達到整個數據變成有序數組。

如下圖:

假設最開始的基準數據為數組的第一個元素23,則首先用一個臨時變數去存儲基準數據,即 tmp=23 ,然後分別從數組的兩端掃描數組,設兩個指示標志: low 指向起始位置, high 指向末尾。

首先從後半部分開始,如果 掃描到的值大於基準數據 就讓 high-1 ,如果發現有元素比該基準數據的值小,比如上面的 18 <= tmp ,就讓 high位置的值賦值給low位置 ,結果如下:

然後開始從前往後掃描,如果掃描到的值小於基準數據就讓 low+1 ,如果發現有元素大於基準數據的值,比如上圖 46 >= tmp ,就再將 low 位置的值賦值給 high 位置的值,指針移動並且數據交換後的結果如下:

然後再開始從前往後遍歷,直到 low=high 結束循環,此時low或者high的下標就是 基準數據23在該數組中的正確索引位置 ,如下圖所示:

這樣一遍遍的走下來,可以很清楚的知道,快排的本質就是把比基準數據小的都放到基準數的左邊,比基準數大的數都放到基準數的右邊,這樣就找到了該數據在數組中的正確位置。

然後採用遞歸的方式分別對前半部分和後半部分排序,最終結果就是自然有序的了。

輸出結果:

最好情況下快排每次能恰好均分序列,那麼時間復雜度就是O(nlogn),最壞情況下,快排每次劃分都只能將序列分為一個元素和其它元素兩部分,這時候的快排退化成冒泡排序,時間復雜度為O(n^2)。

插入排序的基本操作就是將一個數據插入到已經排好序的有序數據中,從而得到一個新的、個數加一的有序數據,演算法適用於少量數據的排序,時間復雜度為O(n^2)。是穩定的排序方法。

將一個數據插入到 已經排好序的有序數據

第一趟排序:

用數組的第二個數與第一個數( 看成是已有序的數據 )比較

第二趟排序:

用數組的第三個數與已是有序的數據 {2,3} (剛才在第一趟排的)比較

在第二步中:

...

後面依此類推

輸出結果:

選擇排序是一種簡單直觀的排序演算法。它的工作原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到全部待排序的數據元素排完。 選擇排序是不穩定的排序方法。

舉例:數組 int[] arr={5,2,8,4,9,1}

第一趟排序 : 原始數據: 5 2 8 4 9 1

最小數據1,把1放在首位,也就是1和5互換位置,

排序結果: 1 2 8 4 9 5

第二趟排序

第1以外的數據 {2 8 4 9 5} 進行比較,2最小,

排序結果: 1 2 8 4 9 5

第三趟排序

除 1、2 以外的數據 {8 4 9 5} 進行比較,4最小,8和4交換

排序結果: 1 2 4 8 9 5

第四趟排序 :

除第 1、2、4 以外的其他數據 {8 9 5} 進行比較,5最小,8和5交換

排序結果: 1 2 4 5 9 8

第五趟排序:

除第 1、2、4、5 以外的其他數據 {9 8} 進行比較,8最小,8和9交換

排序結果: 1 2 4 5 8 9

輸出結果:

歸並排序(merge sort)是利用歸並的思想實現的排序方法,該演算法採用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然後遞歸求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。

比如我們對 [8,4,5,7,1,3,6,2] 這個數組進行歸並排序,我們首先利用分治思想的「分」將數組拆分。

輸出結果:

❷ 幾種排序演算法的比較

一、八大排序演算法的總體比較

4.3、堆的插入:

每次插入都是將新數據放在數組最後。可以發現從這個新數據的父結點到根結點必然為一個有序的數列,然後將這個新數據插入到這個有序數據中

(1)用大根堆排序的基本思想

先將初始數組建成一個大根堆,此對為初始的無序區;

再將最大的元素和無序區的最後一個記錄交換,由此得到新的無序區和有序區,且滿足<=的值;

由於交換後新的根可能違反堆性質,故將當前無序區調整為堆。然後再次將其中最大的元素和該區間的最後一個記錄交換,由此得到新的無序區和有序區,且仍滿足關系的值<=的值,同樣要將其調整為堆;

..........

直到無序區只有一個元素為止;

4.4:應用

尋找M個數中的前K個最小的數並保持有序;

時間復雜度:O(K)[創建K個元素最大堆的時間復雜度] +(M-K)*log(K)[對剩餘M-K個數據進行比較並每次對最大堆進行從新最大堆化]

5.希爾排序

(1)基本思想

先將整個待排序元素序列分割成若乾子序列(由相隔某個「增量」的元素組成的)分別進行直接插入排序,然後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序(因為直接插入排序在元素基本有序的情況下,效率很高);

(2)適用場景

比較在希爾排序中是最主要的操作,而不是交換。用已知最好的步長序列的希爾排序比直接插入排序要快,甚至在小數組中比快速排序和堆排序還快,但在涉及大量數據時希爾排序還是不如快排;

6.歸並排序

(1)基本思想

首先將初始序列的n個記錄看成是n個有序的子序列,每個子序列的長度為1,然後兩兩歸並,得到n/2個長度為2的有序子序列,在此基礎上,再對長度為2的有序子序列進行兩兩歸並,得到若干個長度為4的有序子序列,以此類推,直到得到一個長度為n的有序序列為止;

(2)適用場景

若n較大,並且要求排序穩定,則可以選擇歸並排序;

7.簡單選擇排序

(1)基本思想

第一趟:從第一個記錄開始,將後面n-1個記錄進行比較,找到其中最小的記錄和第一個記錄進行交換;

第二趟:從第二個記錄開始,將後面n-2個記錄進行比較,找到其中最小的記錄和第2個記錄進行交換;

...........

第i趟:從第i個記錄開始,將後面n-i個記錄進行比較,找到其中最小的記錄和第i個記錄進行交換;

以此類推,經過n-1趟比較,將n-1個記錄排到位,剩下一個最大記錄直接排在最後;

❸ 八大經典排序演算法原理及實現

該系列文章主要是記錄下自己暑假這段時間的學習筆記,暑期也在實習,抽空學了很多,每個方面的知識我都會另起一篇博客去記錄,每篇頭部主要是另起博客的鏈接。

冒泡排序演算法應該是大家第一個接觸的演算法,其原理都應該懂,但我還是想以自己的語言來敘述下其步奏:

按照計算時間復雜度的規則,去掉常數、去掉最高項系數,其復雜度為O(N^2)
冒泡排序及其復雜度分析

空間復雜度就是在交換元素時那個臨時變數所佔的內存

給定一個整數序列{6,1,2,3,4},每完成一次外層循環的結果為:

我們發現第一次外層循環之後就排序成功了,但是還是會繼續循環下去,造成了不必要的時間復雜度,怎麼優化?

冒泡排序都是相鄰元素的比較,當相鄰元素相等時並不會交換,因此冒泡排序演算法是穩定性演算法

插入排序是對冒泡排序的一種改進

插入排序的思想是數組是部分有序的,再將無序的部分插入有序的部分中去,如圖:
(圖片來自 這里 )

空間復雜度就是在交換元素時那個臨時變數所佔的內存

插入排序的優化,有兩種方案:

文章後面會給出這兩種排序演算法

由於插入排序也是相鄰元素的比較,遇到相等的相鄰元素時不會發生交換,也不會造成相等元素之間的相對位置發生變化

其原理是從未排序的元素中選出最小值(最大值)放在已排序元素的後面

空間復雜度就是在交換元素時那個臨時變數所佔的內存

選擇排序是不穩定的,比如 3 6 3 2 4,第一次外層循環中就會交換第一個元素3和第四個元素2,那麼就會導致原序列的兩個3的相對位置發生變化

希爾排序算是改良版的插入排序演算法,所以也稱為希爾插入排序演算法

其原理是將序列分割成若乾子序列(由相隔某個 增量 的元素組成的),分別進行直接插入排序;接著依次縮小增量繼續進行排序,待整個序列基本有序時,再對全體元素進行插入排序,我們知道當序列基本有序時使用直接插入排序的效率很高。
上述描述只是其原理,真正的實現可以按下述步奏來:

希爾排序的效率取決於 增量值gap 的選取,這涉及到數學上尚未解決的難題,但是某些序列中復雜度可以為O(N 1.3),當然最好肯定是O(N),最壞是O(N 2)

空間復雜度就是在交換元素時那個臨時變數所佔的內存

希爾排序並不只是相鄰元素的比較,有許多跳躍式的比較,難免會出現相同元素之間的相對位置發生變化,所以希爾排序是不穩定的

理解堆排序,就必須得先知道什麼是堆?

二叉樹的特點:

當父節點的值總是大於子結點時為 最大堆 ;反之為 最小堆 ,下圖就為一個二叉堆

一般用數組來表示堆,下標為 i 的結點的父結點下標為(i-1)/2;其左右子結點分別為 (2 i + 1)、(2 i + 2)

怎麼將給定的數組序列按照堆的性質,調整為堆?

這里以建立最小堆為示例,

很明顯對於其葉子結點來說,已經是一個合法的子堆,所以做堆調整時,子節點沒有必要進行,這里只需從結點為A[4] = 50的結點開始做堆調整,即從(n/2 - 1)位置處向上開始做堆調整:

由於每次重新恢復堆的時間復雜度為O(logN),共N - 1次重新恢復堆操作,再加上前面建立堆時N / 2次向下調整,每次調整時間復雜度也為O(logN),二次操作時間相加還是O(N logN)。故堆排序的時間復雜度為O(N * logN)。

空間復雜度就是在交換元素時那個臨時變數所佔的內存

由於堆排序也是跨越式的交換數據,會導致相同元素之間的相對位置發生變化,則演算法不穩定。比如 5 5 5 ,堆化數組後將堆頂元素5與堆尾元素5交換,使得第一個5和第三個5的相對位置發生變化

歸並排序是建立在歸並操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。

快速排序在應該是大家經常看到、聽到的演算法,但是真正默寫出來是有難度的。希望大家看了下面 挖坑填數 方法後,能快速寫出、快速排序。

其原理就這么幾句話,但是現實起來並不是這么簡單,我們採取流行的一種方式 挖坑填數分治法

對於序列: 72 6 57 88 60 42 83 73 48 85

數組變為: 48 6 57 88 60 42 83 73 88 85
再重復上面的步驟,先從後向前找,再從前向後找:

數組變為: 48 6 57 42 60 72 83 73 88 85
可以看出a[5]前面的數字都小於它,a[5]後面的數字都大於它。因此再對a[0…4]和a[6…9]這二個子區間重復上述步驟就可以了

空間復雜度,主要是遞歸造成的棧空間的使用:

快速排序的優化主要在於基準數的選取

快速排序也是跨越式比較及交換數據,易導致相同元素之間的相對位置發生變化,所以快速排序不穩定

前面也說了二分查找排序是改進的插入排序,不同之處在於,在有序區間查找新元素插入位置時,為了減少比較次數提高效率,採用二分查找演算法進行插入位置的確定
具體步驟,設數組為a[0…n]:

二分查找插入位置,因為不是查找相等值,而是基於比較查插入合適的位置,所以必須查到最後一個元素才知道插入位置。
二分查找最壞時間復雜度:當2^X>=n時,查詢結束,所以查詢的次數就為x,而x等於log2n(以2為底,n的對數)。即O(log2n)
所以,二分查找排序比較次數為:x=log2n
二分查找插入排序耗時的操作有:比較 + 後移賦值。時間復雜度如下:

二分查找排序在交換數據時時進行移動,當遇到有相等值插入時也只會插入其後面,不會影響其相等元素之間的相對位置,所以是穩定的

白話經典演算法排序
冒泡排序選擇排序
快速排序復雜度分析
優化的插入排序

❹ JS常見排序演算法

排序演算法說明:

(1)對於評述演算法優劣術語的說明

穩定 :如果a原本在b前面,而a=b,排序之後a仍然在b的前面;

不穩定 :如果a原本在b的前面,而a=b,排序之後a可能會出現在b的後面;

內排序 :所有排序操作都在內存中完成;

外排序 :由於數據太大,因此把數據放在磁碟中,而排序通過磁碟和內存的數據傳輸才能進行;

時間復雜度 : 一個演算法執行所耗費的時間。

空間復雜度 : 運行完一個程序所需內存的大小。

(2)排序演算法圖片總結:

1.冒泡排序:

解析:1.比較相鄰的兩個元素,如果前一個比後一個大,則交換位置。

2.第一輪的時候最後一個元素應該是最大的一個。

3.按照步驟一的方法進行相鄰兩個元素的比較,這個時候由於最後一個元素已經是最大的了,所以最後一個元素不用比較。

2.快速排序:

解析:快速排序是對冒泡排序的一種改進,第一趟排序時將數據分成兩部分,一部分比另一部分的所有數據都要小。然後遞歸調用,在兩邊都實行快速排序。

3.插入排序:

解析:

 (1) 從第一個元素開始,該元素可以認為已經被排序

 (2) 取出下一個元素,在已經排序的元素序列中從後向前掃描

 (3) 如果該元素(已排序)大於新元素,將該元素移到下一位置

 (4) 重復步驟3,直到找到已排序的元素小於或者等於新元素的位置

 (5)將新元素插入到下一位置中

 (6) 重復步驟2

2.二分查找:

解析:二分查找,也為折半查找。首先要找到一個中間值,通過與中間值比較,大的放又,小的放在左邊。再在兩邊中尋找中間值,持續以上操作,直到找到所在位置為止。

(1)遞歸方法

(2)非遞歸方法

4.選擇排序:

解析:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。

以此類推,直到所有元素均排序完畢。

5.希爾排序:

解析:先將整個待排序的記錄序列分割成為若乾子序列分別進行直接插入排序

6.歸並排序:

解析:歸並排序是一種穩定的排序方法。將已有序的子序列合並,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。

7.堆排序:

解析:堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序演算法。堆積是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是

小於(或者大於)它的父節點。

8.計數排序:

 解析:計數排序使用一個額外的數組C,其中第i個元素是待排序數組A中值等於i的元素的個數。然後根據數組C來將A中的元素排到正確的位置。它只能對整數進行排序。

9.桶排序:

解析:假設輸入數據服從均勻分布,將數據分到有限數量的桶里,每個桶再分別排序(有可能再使用別的排序演算法或是以遞歸方式繼續使用桶排序進行排

10.基數排序:

解析:基數排序是按照低位先排序,然後收集;再按照高位排序,然後再收集;依次類推,直到最高位。有時候有些屬性是有優先順序順序的,先按低優先順序排序,再按高優

先級排序。最後的次序就是高優先順序高的在前,高優先順序相同的低優先順序高的在前。基數排序基於分別排序,分別收集,所以是穩定的。

基數排序 vs 計數排序 vs 桶排序

這三種排序演算法都利用了桶的概念,但對桶的使用方法上有明顯差異:

基數排序:根據鍵值的每位數字來分配桶 計數排序:每個桶只存儲單一鍵值 桶排序:每個桶存儲一定范圍的數值

❺ 十大經典排序演算法

排序演算法是《數據結構與演算法》中最基本的演算法之一。

排序演算法可以分為內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。常見的內部排序演算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸並排序、快速排序、堆排序、基數排序等。用一張圖概括:

點擊以下圖片查看大圖:

關於時間復雜度

平方階 (O(n2)) 排序 各類簡單排序:直接插入、直接選擇和冒泡排序。

線性對數階 (O(nlog2n)) 排序 快速排序、堆排序和歸並排序;

O(n1+§)) 排序,§ 是介於 0 和 1 之間的常數。 希爾排序

線性階 (O(n)) 排序 基數排序,此外還有桶、箱排序。

關於穩定性

穩定的排序演算法:冒泡排序、插入排序、歸並排序和基數排序。

不是穩定的排序演算法:選擇排序、快速排序、希爾排序、堆排序。

名詞解釋:

n:數據規模 k:"桶"的個數 In-place:佔用常數內存,不佔用額外內存 Out-place:佔用額外內存 穩定性:排序後 2 個相等鍵值的順序和排序之前它們的順序相同

包含以下內容:

1、冒泡排序 2、選擇排序 3、插入排序 4、希爾排序 5、歸並排序 6、快速排序 7、堆排序 8、計數排序 9、桶排序 10、基數排序

排序演算法包含的相關內容具體如下:

冒泡排序演算法

冒泡排序(Bubble Sort)也是一種簡單直觀的排序演算法。它重復地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重復地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢"浮"到數列的頂端。

選擇排序演算法

選擇排序是一種簡單直觀的排序演算法,無論什麼數據進去都是 O(n?) 的時間復雜度。所以用到它的時候,數據規模越小越好。唯一的好處可能就是不佔用額外的內存空間。

插入排序演算法

插入排序的代碼實現雖然沒有冒泡排序和選擇排序那麼簡單粗暴,但它的原理應該是最容易理解的了,因為只要打過撲克牌的人都應該能夠秒懂。插入排序是一種最簡單直觀的排序演算法,它的工作原理是通過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。

希爾排序演算法

希爾排序,也稱遞減增量排序演算法,是插入排序的一種更高效的改進版本。但希爾排序是非穩定排序演算法。

歸並排序演算法

歸並排序(Merge sort)是建立在歸並操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。

快速排序演算法

快速排序是由東尼·霍爾所發展的一種排序演算法。在平均狀況下,排序 n 個項目要 Ο(nlogn) 次比較。在最壞狀況下則需要 Ο(n2) 次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他 Ο(nlogn) 演算法更快,因為它的內部循環(inner loop)可以在大部分的架構上很有效率地被實現出來。

堆排序演算法

堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序演算法。堆積是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。堆排序可以說是一種利用堆的概念來排序的選擇排序。

計數排序演算法

計數排序的核心在於將輸入的數據值轉化為鍵存儲在額外開辟的數組空間中。作為一種線性時間復雜度的排序,計數排序要求輸入的數據必須是有確定范圍的整數。

桶排序演算法

桶排序是計數排序的升級版。它利用了函數的映射關系,高效與否的關鍵就在於這個映射函數的確定。

基數排序演算法

基數排序是一種非比較型整數排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。由於整數也可以表達字元串(比如名字或日期)和特定格式的浮點數,所以基數排序也不是只能使用於整數。

❻ 什麼是排序法

排序法是指根據被評估員工的工作績效進行比較,從而確定每一員工的相對等級或名次。等級或名次可從優至劣或由劣到優排列。比較標准可根據員工績效的某一方面(如:出勤率、事故率、優質品率)確定,一般情況下是根據員工的總體工作績效進行綜合比較。

❼ 排序演算法概述

十大排序演算法:冒泡排序,選擇排序,插入排序,歸並排序,堆排序,快速排序、希爾排序、計數排序,基數排序,桶排序

穩定 :如果a原本在b前面,而a=b,排序之後a仍然在b的前面;
不穩定 :如果a原本在b的前面,而a=b,排序之後a可能會出現在b的後面;
排序演算法如果是穩定的,那麼從一個鍵上排序,然後再從另一個鍵上排序,前一個鍵排序的結果可以為後一個鍵排序所用。

演算法的復雜度往往取決於數據的規模大小和數據本身分布性質。
時間復雜度 : 一個演算法執行所耗費的時間。
空間復雜度 :對一個演算法在運行過程中臨時佔用存儲空間大小的量度。
常見復雜度由小到大 :O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n)

在各種不同演算法中,若演算法中語句執行次數(佔用空間)為一個常數,則復雜度為O(1);
當一個演算法的復雜度與以2為底的n的對數成正比時,可表示為O(log n);
當一個演算法的復雜度與n成線性比例關系時,可表示為O (n),依次類推。

冒泡、選擇、插入排序需要兩個for循環,每次只關注一個元素,平均時間復雜度為
(一遍找元素O(n),一遍找位置O(n))
快速、歸並、堆基於分治思想,log以2為底,平均時間復雜度往往和O(nlogn)(一遍找元素O(n),一遍找位置O(logn))相關
而希爾排序依賴於所取增量序列的性質,但是到目前為止還沒有一個最好的增量序列 。例如希爾增量序列時間復雜度為O(n²),而Hibbard增量序列的希爾排序的時間復雜度為 , 有人在大量的實驗後得出結論;當n在某個特定的范圍後希爾排序的最小時間復雜度大約為n^1.3。

從平均時間來看,快速排序是效率最高的:
快速排序中平均時間復雜度O(nlog n),這個公式中隱含的常數因子很小,比歸並排序的O(nlog n)中的要小很多,所以大多數情況下,快速排序總是優於合並排序的。

而堆排序的平均時間復雜度也是O(nlog n),但是堆排序存在著重建堆的過程,它把根節點移除後,把最後的葉子結點拿上來後需要重建堆,但是,拿上的值是要比它的兩個葉子結點要差很多的,一般要比較很多次,才能回到合適的位置。堆排序就會有很多的時間耗在堆調整上。

雖然快速排序的最壞情況為排序規模(n)的平方關系,但是這種最壞情況取決於每次選擇的基準, 對於這種情況,已經提出了很多優化的方法,比如三取樣劃分和Dual-Pivot快排。
同時,當排序規模較小時,劃分的平衡性容易被打破,而且頻繁的方法調用超過了O(nlog n)為
省出的時間,所以一般排序規模較小時,會改用插入排序或者其他排序演算法。

一種簡單的排序演算法。它反復地走訪過要排序的數列,一次比較兩個元素,如果它們的順序錯誤就把它們交換過來。這個工作重復地進行直到沒有元素再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為元素會經由交換慢慢「浮」到數列的頂端。
1.從數組頭開始,比較相鄰的元素。如果第一個比第二個大(小),就交換它們兩個;
2.對每一對相鄰元素作同樣的工作,從開始第一對到尾部的最後一對,這樣在最後的元素應該會是最大(小)的數;
3.重復步驟1~2,重復次數等於數組的長度,直到排序完成。

首先,找到數組中最大(小)的那個元素;
其次,將它和數組的第一個元素交換位置(如果第一個元素就是最大(小)元素那麼它就和自己交換);
再次,在剩下的元素中找到最大(小)的元素,將它與數組的第二個元素交換位置。如此往復,直到將整個數組排序。
這種方法叫做選擇排序,因為它在不斷地選擇剩餘元素之中的最大(小)者。

對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。
為了給要插入的元素騰出空間,我們需要將插入位置之後的已排序元素在都向後移動一位。
插入排序所需的時間取決於輸入中元素的初始順序。例如,對一個很大且其中的元素已經有序(或接近有序)的數組進行排序將會比對隨機順序的數組或是逆序數組進行排序要快得多。
總的來說,插入排序對於部分有序的數組十分高效,也很適合小規模數組。

一種基於插入排序的快速的排序演算法。簡單插入排序對於大規模亂序數組很慢,因為元素只能一點一點地從數組的一端移動到另一端。例如,如果主鍵最小的元素正好在數組的盡頭,要將它挪到正確的位置就需要N-1 次移動。
希爾排序為了加快速度簡單地改進了插入排序,也稱為縮小增量排序,同時該演算法是突破O(n^2)的第一批演算法之一。
希爾排序是把待排序數組按一定數量的分組,對每組使用直接插入排序演算法排序;然後縮小數量繼續分組排序,隨著數量逐漸減少,每組包含的元素越來越多,當數量減至 1 時,整個數組恰被分成一組,排序便完成了。這個不斷縮小的數量,就構成了一個增量序列。

在先前較大的增量下每個子序列的規模都不大,用直接插入排序效率都較高,盡管在隨後的增量遞減分組中子序列越來越大,由於整個序列的有序性也越來越明顯,則排序效率依然較高。
從理論上說,只要一個數組是遞減的,並且最後一個值是1,都可以作為增量序列使用。有沒有一個步長序列,使得排序過程中所需的比較和移動次數相對較少,並且無論待排序列記錄數有多少,演算法的時間復雜度都能漸近最佳呢?但是目前從數學上來說,無法證明某個序列是「最好的」。
常用的增量序列
希爾增量序列 :{N/2, (N / 2)/2, ..., 1},其中N為原始數組的長度,這是最常用的序列,但卻不是最好的
Hibbard序列:{2^k-1, ..., 3,1}
Sedgewick序列:{... , 109 , 41 , 19 , 5,1} 表達式為

歸並排序是建立在歸並操作上的一種有效的排序演算法。該演算法是採用分治法的一個非常典型的應用。
對於給定的一組數據,利用遞歸與分治技術將數據序列劃分成為越來越小的半子表,在對半子表排序後,再用遞歸方法將排好序的半子表合並成為越來越大的有序序列。
為了提升性能,有時我們在半子表的個數小於某個數(比如15)的情況下,對半子表的排序採用其他排序演算法,比如插入排序。
若將兩個有序表合並成一個有序表,稱為2-路歸並,與之對應的還有多路歸並。

快速排序(Quicksort)是對冒泡排序的一種改進,也是採用分治法的一個典型的應用。
首先任意選取一個數據(比如數組的第一個數)作為關鍵數據,我們稱為基準數(Pivot),然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序,也稱為分區(partition)操作。
通過一趟快速排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數組變成有序序列。
為了提升性能,有時我們在分割後獨立的兩部分的個數小於某個數(比如15)的情況下,會採用其他排序演算法,比如插入排序。

基準的選取:最優的情況是基準值剛好取在無序區數值的中位數,這樣能夠最大效率地讓兩邊排序,同時最大地減少遞歸劃分的次數,但是一般很難做到最優。基準的選取一般有三種方式,選取數組的第一個元素,選取數組的最後一個元素,以及選取第一個、最後一個以及中間的元素的中位數(如4 5 6 7, 第一個4, 最後一個7, 中間的為5, 這三個數的中位數為5, 所以選擇5作為基準)。
Dual-Pivot快排:雙基準快速排序演算法,其實就是用兩個基準數, 把整個數組分成三份來進行快速排序,在這種新的演算法下面,比經典快排從實驗來看節省了10%的時間。

許多應用程序都需要處理有序的元素,但不一定要求他們全部有序,或者不一定要一次就將他們排序,很多時候,我們每次只需要操作數據中的最大元素(最小元素),那麼有一種基於二叉堆的數據結構可以提供支持。
所謂二叉堆,是一個完全二叉樹的結構,同時滿足堆的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。在一個二叉堆中,根節點總是最大(或者最小)節點。
堆排序演算法就是抓住了這一特點,每次都取堆頂的元素,然後將剩餘的元素重新調整為最大(最小)堆,依次類推,最終得到排序的序列。

推論1:對於位置為K的結點 左子結點=2 k+1 右子結點=2 (k+1)
驗證:C:2 2 2+1=5 2 (2+1)=6
推論2:最後一個非葉節點的位置為 (N/2)-1,N為數組長度。
驗證:數組長度為6,(6/2)-1=2

計數排序對一定范圍內的整數排序時候的速度非常快,一般快於其他排序演算法。但計數排序局限性比較大,只限於對整數進行排序,而且待排序元素值分布較連續、跨度小的情況。
計數排序是一個排序時不比較元素大小的排序演算法。
如果一個數組里所有元素都是整數,而且都在0-K以內。對於數組里每個元素來說,如果能知道數組里有多少項小於或等於該元素,就能准確地給出該元素在排序後的數組的位置。

桶排序 (Bucket sort)的工作的原理:假設輸入數據服從均勻分布,利用某種函數的映射關系將數據分到有限數量的桶里,每個桶再分別排序(有可能再使用別的排序演算法或是以遞歸方式繼續使用桶排序)。
桶排序利用函數的映射關系,減少了幾乎所有的比較工作。實際上,桶排序的f(k)值的計算,其作用就相當於快排中劃分,已經把大量數據分割成了基本有序的數據塊(桶)。然後只需要對桶中的少量數據做排序即可。

常見的數據元素一般是由若干位組成的,比如字元串由若干字元組成,整數由若干位0~9數字組成。基數排序按照從右往左的順序,依次將每一位都當做一次關鍵字,然後按照該關鍵字對數組排序,同時每一輪排序都基於上輪排序後的結果;當我們將所有的位排序後,整個數組就達到有序狀態。基數排序不是基於比較的演算法。
基數是什麼意思?對於十進制整數,每一位都只可能是0~9中的某一個,總共10種可能。那10就是它的基,同理二進制數字的基為2;對於字元串,如果它使用的是8位的擴展ASCII字元集,那麼它的基就是256。

基數排序 vs 計數排序 vs 桶排序

基數排序有兩種方法:
MSD 從高位開始進行排序
LSD 從低位開始進行排序
這三種排序演算法都利用了桶的概念,但對桶的使用方法上有明顯差異:
基數排序:根據鍵值的每位數字來分配桶
計數排序:每個桶只存儲單一鍵值
桶排序:每個桶存儲一定范圍的數值

有時,待排序的文件很大,計算機內存不能容納整個文件,這時候對文件就不能使用內部排序了(我們一般的排序都是在內存中做的,所以稱之為內部排序,而外部排序是指待排序的內容不能在內存中一下子完成,它需要做內外存的內容交換),外部排序常採用的排序方法也是歸並排序,這種歸並方法由兩個不同的階段組成:
採用適當的內部排序方法對輸入文件的每個片段進行排序,將排好序的片段(成為歸並段)寫到外部存儲器中(通常由一個可用的磁碟作為臨時緩沖區),這樣臨時緩沖區中的每個歸並段的內容是有序的。
利用歸並演算法,歸並第一階段生成的歸並段,直到只剩下一個歸並段為止。

例如要對外存中4500個記錄進行歸並,而內存大小隻能容納750個記錄,在第一階段,我們可以每次讀取750個記錄進行排序,這樣可以分六次讀取,進行排序,可以得到六個有序的歸並段
每個歸並段的大小是750個記錄,並將這些歸並段全部寫到臨時緩沖區(由一個可用的磁碟充當)內了,這是第一步的排序結果。
完成第二步該怎麼做呢?這時候歸並演算法就有用處了。

❽ 排序演算法有多少種

排序(Sorting) 是計算機程序設計中的一種重要操作,它的功能是將一個數據元素(或記錄)的任意序列,重新排列成一個關鍵字有序的序列。
排序就是把集合中的元素按照一定的次序排序在一起。一般來說有升序排列和降序排列2種排序,在演算法中有8中基本排序:
(1)冒泡排序;
(2)選擇排序;
(3)插入排序;
(4)希爾排序;
(5)歸並排序;
(6)快速排序;
(7)基數排序;
(8)堆排序;
(9)計數排序;
(10)桶排序。
插入排序
插入排序演算法是基於某序列已經有序排列的情況下,通過一次插入一個元素的方式按照原有排序方式增加元素。這種比較是從該有序序列的最末端開始執行,即要插入序列中的元素最先和有序序列中最大的元素比較,若其大於該最大元素,則可直接插入最大元素的後面即可,否則再向前一位比較查找直至找到應該插入的位置為止。插入排序的基本思想是,每次將1個待排序的記錄按其關鍵字大小插入到前面已經排好序的子序列中,尋找最適當的位置,直至全部記錄插入完畢。執行過程中,若遇到和插入元素相等的位置,則將要插人的元素放在該相等元素的後面,因此插入該元素後並未改變原序列的前後順序。我們認為插入排序也是一種穩定的排序方法。插入排序分直接插入排序、折半插入排序和希爾排序3類。
冒泡排序
冒泡排序演算法是把較小的元素往前調或者把較大的元素往後調。這種方法主要是通過對相鄰兩個元素進行大小的比較,根據比較結果和演算法規則對該二元素的位置進行交換,這樣逐個依次進行比較和交換,就能達到排序目的。冒泡排序的基本思想是,首先將第1個和第2個記錄的關鍵字比較大小,如果是逆序的,就將這兩個記錄進行交換,再對第2個和第3個記錄的關鍵字進行比較,依次類推,重復進行上述計算,直至完成第(n一1)個和第n個記錄的關鍵字之間的比較,此後,再按照上述過程進行第2次、第3次排序,直至整個序列有序為止。排序過程中要特別注意的是,當相鄰兩個元素大小一致時,這一步操作就不需要交換位置,因此也說明冒泡排序是一種嚴格的穩定排序演算法,它不改變序列中相同元素之間的相對位置關系。
選擇排序
選擇排序演算法的基本思路是為每一個位置選擇當前最小的元素。選擇排序的基本思想是,基於直接選擇排序和堆排序這兩種基本的簡單排序方法。首先從第1個位置開始對全部元素進行選擇,選出全部元素中最小的給該位置,再對第2個位置進行選擇,在剩餘元素中選擇最小的給該位置即可;以此類推,重復進行「最小元素」的選擇,直至完成第(n-1)個位置的元素選擇,則第n個位置就只剩唯一的最大元素,此時不需再進行選擇。使用這種排序時,要注意其中一個不同於冒泡法的細節。舉例說明:序列58539.我們知道第一遍選擇第1個元素「5」會和元素「3」交換,那麼原序列中的兩個相同元素「5」之間的前後相對順序就發生了改變。因此,我們說選擇排序不是穩定的排序演算法,它在計算過程中會破壞穩定性。
快速排序
快速排序的基本思想是:通過一趟排序演算法把所需要排序的序列的元素分割成兩大塊,其中,一部分的元素都要小於或等於另外一部分的序列元素,然後仍根據該種方法對劃分後的這兩塊序列的元素分別再次實行快速排序演算法,排序實現的整個過程可以是遞歸的來進行調用,最終能夠實現將所需排序的無序序列元素變為一個有序的序列。
歸並排序
歸並排序演算法就是把序列遞歸劃分成為一個個短序列,以其中只有1個元素的直接序列或者只有2個元素的序列作為短序列的遞歸出口,再將全部有序的短序列按照一定的規則進行排序為長序列。歸並排序融合了分治策略,即將含有n個記錄的初始序列中的每個記錄均視為長度為1的子序列,再將這n個子序列兩兩合並得到n/2個長度為2(當凡為奇數時會出現長度為l的情況)的有序子序列;將上述步驟重復操作,直至得到1個長度為n的有序長序列。需要注意的是,在進行元素比較和交換時,若兩個元素大小相等則不必刻意交換位置,因此該演算法不會破壞序列的穩定性,即歸並排序也是穩定的排序演算法。

熱點內容
寬頻撥號連接中賬戶密碼是什麼 發布:2025-03-17 23:49:06 瀏覽:359
android貪吃蛇 發布:2025-03-17 23:45:57 瀏覽:69
zbar源碼 發布:2025-03-17 23:42:18 瀏覽:771
水星wifi改密碼怎麼改 發布:2025-03-17 23:41:39 瀏覽:791
編程班表 發布:2025-03-17 23:41:34 瀏覽:882
網上鄰居訪問許可權 發布:2025-03-17 23:41:31 瀏覽:391
國行安卓11如何使用谷歌 發布:2025-03-17 23:40:52 瀏覽:147
ftp數據傳輸和控制埠 發布:2025-03-17 23:40:52 瀏覽:876
首演算法 發布:2025-03-17 23:40:02 瀏覽:452
php應用程序池 發布:2025-03-17 23:36:13 瀏覽:411