經典排序算法複習及筆記(包括講解排序算法穩定性,快排爲例)(面試必問)

https://www.cnblogs.com/onepixel/p/7674659.html - 十大經典排序算法(動圖演示)

6、快速排序(Quick Sort)

快速排序的基本思想:通過一趟排序將待排記錄分隔成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。

6.1 算法描述

相關概念

  • 穩定如果a原本在b前面,而a=b,排序之後a仍然在b的前面。
  • 不穩定:如果a原本在b的前面,而a=b,排序之後 a 可能會出現在 b 的後面。
  • 時間複雜度:對排序數據的總的操作次數。反映當n變化時,操作次數呈現什麼規律。
  • 空間複雜度:是指算法在計算機內執行時所需存儲空間的度量,它也是數據規模n的函數。 

問:爲什麼比較排序算法中,排序算法插入、歸併、冒泡排序是穩定的,而其他排序是不穩定的?

插入:是不斷地向後縮小序列,然後選擇後面的最小的放到前面,而插入的位置向後放置。這裏就保證了前一個元素不會跑到後一個元素後面。

冒泡:是採取整體的策略,它從頭到末尾把最大的元素像氣泡那樣放置到最後,在期間是比較前一個元素和後一個元素,如果前一個元素大於後面元素則交換,等於或小於則不交換,這就導致小或等的前一個絕不能來到後面。·

歸併:歸併採取分治法:先把列劃分位幾個局部,通過在它們之前排序。而歸併中採用2路歸併,就是兩個子序列比較,如果前一個序列當前元素小於或等於後一個序列當前元素,放進排序列表,當前子序列索引index1++。後一個大於前一個放進排序列表,當前子序列縮影index2++。並沒有把相等的元素交換到位置。

而其他不穩定的排序算法,爲什麼不穩定,說到底,就是在排序的過程中,並沒有做好:加入前一個元素小於後一個元素,在排序的過程中把前一個放到了後面。這經常見於排序算法中比較大小時使用了swap的函數,交換位置。

而問不穩定的常見於快排。

快排算法如下:

快速排序使用分治法來把一個串(list)分爲兩個子串(sub-lists)。具體算法描述如下:

  • 從數列中挑出一個元素,稱爲 “基準”(pivot);(一般是挑首個元素作爲基準)
  • 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作;(其實就是通過index索引,當確定基準後,通過索引index=基準+1,遍歷比較在這個子串的元素,當比基準小,交換索引和該元素。索引index++)
  • 遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。

快排不穩定原因:快排因爲排序是通過基準,索引、和序列範圍。通過遞歸的方式進行排序,而比較則是比較基準和當前索引及以後的元素,比當前基準的元素小,則把當前索引(當前及前面比基準元素小,後爲大)和後面比基準小的元素位置做交換。假如組後索引和基準位置做交換,而前索引前爲arr(基準=3),a=2,b=2,用了swap函數,交換arr和b,則成了b,a,arr.位置則交換了。所以不是穩定算法。

堆:他的增刪改查的最好和最壞情況的在排序二叉樹上操作,都是有約束的,所以是不穩定的。(這裏更正一下,堆排序的過程中,相等元素是怎麼排序的???後序再更)

 

最好最壞時間複雜度都不變的是:

堆:(無需多言,凡是使用樹做排序的時間複雜度都是一樣的)

插入排序:無論如何都要從頭都搜索,縮小一個個字符串搜索。

選擇,和堆相似,都是無論如何都要從頭都搜索,縮小一個個字符串搜索。但不同的是選擇插入使用的是插入該位置,位置後面的元素向後放置,而選擇是直接交換插入元素位置和選擇位置元素的位置。

再說時間負責度O(n2)和O(nlog2n)

凡是線性和整體排序的都是O(n2),而使用樹結構或分治算法從局部都整體的都是O(nlog2n).注意希爾排序雖然也劃分不同的序列,但非常注重整體。只不過是把劃分序列而已,而在序列中排序的算法依然是直接插入排序。但爲什麼算法複雜度最好最壞不同呢?其實加入在最好的情況下回採用局部序列前後端比較如果剛好小於就不用排序。但是歸併也採用局部卻是最好最壞都一樣,是因爲兩個子序列歸併的時候採用二路歸算法,每一個元素都要遍歷比較~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章