您好,登錄后才能下訂單哦!
著名數據專家沃斯曾說:算法+數據結構=程序
上次講了數據結構
這回就講講算法
復雜度分析,是貫徹數據結構和算法中的一項基礎技能,學習數據結構和算法的目的,無非就是要寫出占用空間更小、運行時間更短的代碼。
T(n) = O(f(n))
多項式量級:
非多項式量級:(n越多,執行時間急劇上升,性能低)
可以用遞歸的條件:
寫遞歸算法的思路:
遞歸代碼的弊端:
衡量排序算法好壞的三要素:
按時間復雜度分類:
原理: 從下往上,逐次比較兩個相鄰的數據,如果下面的數據比上面的數據大,則把這兩個數據的位置互換。
原理: 分為已排區域和未排區域,每次拿未排區域中的第一個數,插入到已排區域中正確的位置。
原理: 分為已排區域和未排區域,每次從未排區域中選取最小的數,放到已排區域的最后面。
原理: 歸并排序的核心思想還是蠻簡單的。如果要排序一個數組,我們先把數組從中間分成前后兩部分,然后對前后兩部分分別排序,再將排好序的兩部分合并在一起,這樣整個數組就都有序了。
merge_sort(p…r) = merge(merge_sort(p…q), merge_sort(q+1…r))
quick_sort(p…r) = partition(p…r) + quick_sort(p…q-1) + quick_sort(q+1, r)
桶排序,顧名思義,會用到“桶”,核心思想是將要排序的數據分到幾個有序的桶里,每個桶里的數據再單獨進行排序。桶內排完序之后,再把每個桶里的數據按照順序依次取出,組成的序列就是有序的了。
桶排序的時間復雜度為什么是 O(n) 呢?我們一塊兒來分析一下。如果要排序的數據有 n 個,我們把它們均勻地劃分到 m 個桶內,每個桶里就有 k=n/m 個元素。每個桶內部使用快速排序,時間復雜度為 O(k * logk)。m 個桶排序的時間復雜度就是 O(m * k * logk),因為 k=n/m,所以整個桶排序的時間復雜度就是 O(n*log(n/m))。當桶的個數 m 接近數據個數 n 時,log(n/m) 就是一個非常小的常量,這個時候桶排序的時間復雜度接近 O(n)。
苛刻的條件:
計數排序其實是桶排序的一種特殊情況: 數據的訪問很小(例如年齡、考生的成績),桶的數量是有限的。 以給高考考生成績進行排名為例,考生的滿分是 900 分,最小是 0 分,對應901個桶,把全國的考生放入這901個桶,桶內的數據都是分數相同的考生,所以并不需要再進行排序。
特殊要求:
我們再來看這樣一個排序問題。假設我們有 10 萬個手機號碼,希望將這 10 萬個手機號碼從小到大排序,你有什么比較快速的排序方法呢?
我們之前講的快排,時間復雜度可以做到 O(nlogn),還有更高效的排序算法嗎?桶排序、計數排序能派上用場嗎?手機號碼有 11 位,范圍太大,顯然不適合用這兩種排序算法。針對這個排序問題,有沒有時間復雜度是 O(n) 的算法呢?現在我就來介紹一種新的排序算法,基數排序。
剛剛這個問題里有這樣的規律:假設要比較兩個手機號碼 a,b 的大小,如果在前面幾位中,a 手機號碼已經比 b 手機號碼大了,那后面的幾位就不用看了。
借助穩定排序算法,這里有一個巧妙的實現思路。還記得我們第 11 節中,在闡述排序算法的穩定性的時候舉的訂單的例子嗎?我們這里也可以借助相同的處理思路,先按照最后一位來排序手機號碼,然后,再按照倒數第二位重新排序,以此類推,最后按照第一位重新排序。經過 11 次排序之后,手機號碼就都有序了。
手機號碼稍微有點長,畫圖比較不容易看清楚,我用字符串排序的例子,畫了一張基數排序的過程分解圖,你可以看下。
注意,這里按照每位來排序的排序算法要是穩定的,否則這個實現思路就是不正確的。因為如果是非穩定排序算法,那最后一次排序只會考慮最高位的大小順序,完全不管其他位的大小關系,那么低位的排序就完全沒有意義了。
根據每一位來排序,我們可以用剛講過的桶排序或者計數排序,它們的時間復雜度可以做到 O(n)。如果要排序的數據有 k 位,那我們就需要 k 次桶排序或者計數排序,總的時間復雜度是 O(k*n)。當 k 不大的時候,比如手機號碼排序的例子,k 最大就是 11,所以基數排序的時間復雜度就近似于 O(n)。
實際上,有時候要排序的數據并不都是等長的,比如我們排序牛津字典中的 20 萬個英文單詞,最短的只有 1 個字母,最長的我特意去 查了下,有 45 個字母,中文翻譯是塵肺病。對于這種不等長的數據,基數排序還適用嗎?
實際上,我們可以把所有的單詞補齊到相同長度,位數不夠的可以在后面補“0”,因為根據ASCII 值,所有字母都大于“0”,所以補“0”不會影響到原有的大小順序。這樣就可以繼續用基數排序了。
我來總結一下,基數排序對要排序的數據是有要求的:
學習視頻內容可以看這里: https://zhuanlan.zhihu.com/p/96231226
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。