如果我問你:排序演算法的「穩定性」有何意義?你怎麼回答?

朱小廝的部落格發表於2022-12-08

如果我問你:排序演算法的「穩定性」有何意義?你怎麼回答?

雖然我們在工作不一定經常去寫排序演算法,但是排序演算法卻是充斥著我們的程式生活,比如你不經意間呼叫了SDK中的某個sort演算法,其背後無非是什麼快排、歸併等演算法。而且在我們面試的過程中也會經常被問及,如果你在面試的過程中連一個最基本的氣泡排序都不會寫的話,那麼很明顯的面試結果也不會好到哪裡去。

除了基本的實現之外,我們關注排序演算法的同時,往往還會關注它的時間複雜度和空間複雜度。在面試之前,我們可能還會臨時抱佛腳的去記一下其穩定性。下表中列舉了幾種常見的排序演算法的核心總結。

如果我問你:排序演算法的「穩定性」有何意義?你怎麼回答?

對於時間複雜度和空間複雜度這種倒是好理解,如果你經常刷leetcode,就會非常關注此類問題。但是「穩定性」這個屬性往往被我們所忽視,我們一般會記住穩定性的定義以及特定演算法所對應的穩定性,但是是否想過「穩定性」有何意義?

穩定性的定義:假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中,ri=rj,且ri在rj之前,而在排序後的序列中,ri仍在rj之前,則稱這種排序演算法是穩定的;否則稱為不穩定的。

如果我們只是面對簡單的數字排序,那麼穩定性確實也沒有多大意義。比如,1 2 3 3 4的序列中如果第一個3和第二個3在sort方法反覆執行之後位置也反覆變化,但是對於呼叫sort方法所想要獲得排序結果的上游應用而言,那麼結果還是1 2 3 3 4,至於3的次序,無關緊要。

如果排序的內容僅僅是一個複雜物件的某一個數字屬性,那麼穩定性依舊將毫無意義(所謂的交換操作的開銷已經算在演算法的開銷內了,如果嫌棄這種開銷,不如換演算法好了?

如果要排序的內容是一個複雜物件的多個數字屬性,但是其原本的初始順序毫無意義,那麼穩定性依舊將毫無意義。

那麼排序演算法的「穩定性」在什麼情況下才會變得有意義呢?

舉個例子,一個班的學生已經按照學號大小排好序了,我現在要求按照年齡從小到大再排個序,如果年齡相同的,必須按照學號從小到大的順序排列。那麼問題來了,你選擇的年齡排序方法如果是不穩定的,是不是排序完了後年齡相同的一組學生學號就亂了,你就得把這組年齡相同的學生再按照學號拍一遍。如果是穩定的排序演算法,我就只需要按照年齡排一遍就好了。

從一個鍵上排序,然後再從另一個鍵上排序,第一個鍵排序的結果可以為第二個鍵排序所用。要排序的內容是一個複雜物件的多個數字屬性,且其原本的初始順序存在意義,那麼我們需要在二次排序的基礎上保持原有排序的意義,才需要使用到穩定性的演算法。

排序演算法的「穩定性」有何意義?這個還是要分應用場景來看,很多使用情況下,並沒有什麼實質的意義,而在有些情況下卻有很重要的意義。

有很多演算法你現在看著沒啥,但是當放在大資料雲端計算的條件下它的穩定性非常重要。舉個例子來說,對淘寶網的商品進行排序,按照銷量,價格等條件進行排序,它的資料伺服器中的資料非常多,因此,當時用一個穩定性效果不好的排序演算法,如堆排序、shell排序,當遇到最壞情形,會使得排序的效果非常差,嚴重影響伺服器的效能,影響到使用者的體驗。

排序演算法的「穩定性」有何意義?你以前是否忽略了這個問題,那麼現在你Get到了嗎?或者你有更好的答案,歡迎在文末留言。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69940568/viewspace-2659764/,如需轉載,請註明出處,否則將追究法律責任。

相關文章