排序演算法介紹及實現 選擇 冒泡 歸併 快排等

2021-10-22 07:33:10 字數 3236 閱讀 9776

記錄一下最近學習的各種排序演算法。

插入排序

氣泡排序

歸併排序

快速排序

選擇排序是最簡單且容易想到的排序方法。它把輸入值(以下均以列表為例)分為兩個部分:已排序 和 未排序部分。

先看一組偽**:

}//找到餘下值中最小的索引值,與第i個值交換。若沒找到則不變

temp = numbers[i]

numbers[i]

= numbers[indexsmallest

numbers[indexsmallest]

= temp

}兩個迴圈把列表分為已排序和未排序兩部分,用 i,j 去表示

該演算法找到未排序中最小值的索引值

把索引值上的元素與i元素交換

i,j 更新,表示出新的已排序未排序部分

直到 i 小於長度 -1,遍歷停止。因為不再需要單獨遍歷最後乙個元素。

該演算法或將執行多次比較。當列表長度為n時,外層迴圈將執行 n - 1 次。在這些外迴圈中,內層迴圈每次將執行平均 n / 2 次。所以,(n - 1) x (n / 2) = o(n ^ 2)。此演算法也是眾多排序演算法中最慢的演算法之一。

同樣的,插入排序也將列表分為已排序和未排序部分。不同的是,此演算法每次只在未排序部分中提取第乙個元素,然後把它放到已排序部分中合適的位置。

先看一組偽**:

}這次要外層要迴圈到長度而不是長度 - 1,因為我們也要把最後乙個元素放到正確的位置上。

將第i個元素作為第乙個未排序部分的起點。因為我們無需排序索引0,所以 i 為1。

第j個元素一直標記為我們要插入的元素。如果該元素比前乙個元素小,則互換。

當第i個元素放置到正確的位置後,i + 1。迴圈下一位元素並放置到正確位置。

如果要插入的元素比前面所有元素值都要小,則該元素依次迴圈到列表第一位,隨之 j = 0打破迴圈。

該演算法實際上效率與選擇排序同理,複雜度均為o(n^2)。因為外層迴圈執行n - 1次,而內層迴圈同樣每次平均執行n/2 次。(n - 1) x (n / 2) = o(n ^ 2)。

該演算法不再將列表分為兩個部分,每次只比較兩個相鄰的元素然後調整位置。

先看一組偽**:

for

(i =

0; i < numberssize -1;

++i)

}}

該演算法從第乙個元素開始,依次和後面的元素比較。若後一位元素小於前一位元素則互換。

內層迴圈結束後,該列表中最大的元素已確定到最後一位。然後重新遍歷列表。

當 i = 長度 - 1 時,結束遍歷,此時列表已排好序。

與前兩種演算法不同,該演算法依次優先排好後面的順序,而不是前面。

因為巢狀迴圈,該演算法的時間複雜度仍為o(n^2)。

該演算法用到遞迴解決,分為兩個部分。第乙個部分為遞迴函式,該函式每次平均把列表分為兩個部分,分別去遞迴。第二個部分為乙個排序函式,用來排遞迴回來的列表。

來看兩組偽**:

//遞迴函式內容:

merge

(numbers, start, end)

//排序函式

mergehelper

(numbers, start, mid, end)

else

++mergepos

}//當左邊沒新增完,右邊已經新增完時,把左邊剩下的加到mergednumbers

while

(leftpos <= mid)

//右邊同理

while

(rightpos <= end)

//最後,把排好序的列表放回到原列表中

for(mergepos =

0; mergepos < mergedsize;

++mergepos)

}

思路已寫在注釋中。

該演算法重複平分列表直到每個列表的元素數為1。此做法會構成log n層列表。每層列表中執行n次比較運算,所以一共有 n * log n次運算,而該演算法成為最有效率的排序演算法之一。

與歸併排序類似,快排也用到了遞迴去解決問題。該演算法隨意取乙個元素為基準數pivot。把所有比它小的元素放在它的前面,比它大的元素放在後面。在以pivot為中心把列表分別遞迴,直到個數為1。

再來看兩組偽**:

quicksort

(numbers, lowindex, highindex)

//lowendindex為小於的部分的最後乙個元素

lowendindex =

partition

(numbers, lowindex, highindex)

//遞迴小於的部分和大於的部分

quicksort

(numbers, lowindex, lowendindex)

quicksort

(numbers, lowendindex +

1, highindex)

}

partition

(numbers, lowindex, highindex)

//當numbers[highindex] > pivot時,增加highindex

while

(numbers[highindex]

> pivot)

if(lowindex >= highindex)

else

}return highindex

}

思路已寫在注釋中。

通常來說,該演算法的時間複雜的為o(n log n)。特殊情況下,當每一層的pivot都選擇了最大或是最小的元素,則此情況下的時間複雜度為o(n^2)。但是由於這種情況的發生概率小之又小,該演算法是最有效率的排序演算法之一。

後面會更新更多的排序演算法,此部落格僅用於自我學習的記錄,如有不當請指正。

選擇 冒泡 歸併 插入及希爾排序

選擇排序每次遍歷一遍陣列,找出最小的數,然後跟陣列的第乙個元素交換。再從剩下的元素中重複此步驟直至陣列排序完畢。時間複雜度與輸入資料無關,為o n 2 每次從首元素開始,從左到右交換相鄰且逆序的元素,一直交換到尾元素時即完成一輪迴圈,此時末尾元素即為最大值。接著在除尾元素外的剩餘元素中繼續上述迴圈,...

演算法之旅 氣泡排序及選擇排序

氣泡排序和選擇排序是排序演算法中比較簡單的兩種演算法。氣泡排序的思想是 比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對,針對所有的元素重複以上的步驟,這樣每次參與比較的元素就越來越少,直到沒有任何一對數字需要比較。對n個數字進行氣泡排...

Java演算法之排序(快速,冒泡,歸併,選擇)

下面是個人整理的幾種排序演算法,不算太難,有一定基礎的認真看看都可理解。歸併演算法思想比較簡單,但在寫 時要注意處理好邊界問題,注意對陣列的賦值和改變。選擇排序 選擇排序 public class n1 1 public n1 1 int a public int result temp a i a...