Lesson 5: 不過就是排序,有什麼難的?
演算法概論
輸入 -> 方法 -> 輸出
輸出:Yes
輸出:123, 132, 213, 231, 312, 321
(但懂了會比較聽得懂)
平均狀態下,一個演算法需要多少時間來完成
n = 10
數列: 10, 1, 93, 12, 94, 11, 102, 4, 2, 38
怎麼查?
阿不就每次都從第一筆看到最後一筆嗎
時間複雜度:O(nm)
每次要找數字,都一定要從第一個查到最後一個
10, 1, 93, 12, 94, 11, 102, 4, 2, 38
排序過後: 1, 2, 4, 10, 11, 12, 38, 93, 94, 102
利用排序過後的特性(後面一定大於前面)
可以做些什麼事情?
假設現在有2個數字,猜2次一定可以猜中
假設現在有4個數字,猜3次一定可以猜中
假設現在有8個數字,猜4次一定可以猜中
1 2 3 4 5 6 7 8,如果我猜4,答案有三種
第一種是答案就是4,那就中了
第二種是範圍變成剩1, 2, 3可以猜
第三種是範圍變成剩5, 6, 7, 8可以猜
依據上面所推出的,4個數字猜3次一定可以猜中
以此類推,16個數字,猜5次一定中
32個數字,猜6次,64個猜七次,128個猜八次
所以100個數字,猜7次一定可以猜中
藉由排序過後的特性,一直從中間切切切切切
就不必從頭到尾找數字,而是能更有方法、效率地去找
時間複雜度從原本的O(n^2)變成
從還沒排序的數列裡面找到最小的,然後移到最左邊
由左到右兩兩比較,把比較大的數字往右邊移
也因為這樣,可以想成是比較大的數字會「浮上來」
因此取名叫做泡沫排序法
其實就是你玩撲克牌的時候,會用到的排序法
從左邊開始,把每一張牌都插入到應該在的位置
有一種方法叫做Divide and Conquer
把大問題分割成小問題,把小問題解決以後,大問題也解決了
假設你現在有個數列是1, 4, 3, 7, 9, 2, 5, 8
分割成兩半,1, 4, 3, 7跟9, 2, 5, 8
個別做好排序以後,就是1, 3, 4, 7跟2, 5, 8, 9
那現在要怎麼把兩個排序好的數列變成一個?
很簡單,你先看兩邊最左邊的數字,發現1比較小
於是就放1,再來看左邊第二個跟右邊第一個,取2
接著左二(3)跟右二(5),取左二
再來左三(4)跟右二(5),取左三
再來左四(7)跟右二(5),取右二
以此類推
最後就可以組合出一個排序好的數列
顧名思義,就是很快的排序法
挑選一個基準點(pivot)
保證左邊的數字都小於它,右邊的數字都大於它
然後對左右兩邊重複此項操作
因為數字的範圍遠比數字數量小太多了
所以我們可以用計數的方法
算算個1有幾個, 2有幾個...100有幾個
就可以達成排序的效果了