最近在看演算法,自然而然地就看到了排序。下面記錄一下自己的學習過程。
一、歸併排序
首先我說說我理解的歸併演算法的核心:歸即將陣列中分為小部分的集合,其中也即數成為區域性有序的集合。然後再將這些有序陣列合併起來。
歸:一般以中點劃分,不斷地遞迴,以使陣列有序,其實歸和並是互動的。如8個數字,歸為4,4。4又歸為2,2。2又歸為1,1。1,1之後不能再劃分,就合併。合併之後是有序的,1,1合併為2,2,2合併為4......如此歸併最終整個有序了。那麼問題來了:歸怎麼實現?並又怎麼實現?歸可以通過遞迴,不斷地劃分。這個實現起來不難。並是將兩個有序的陣列組合在一起,這個組合之後也必須是有序的。將兩個有序陣列結合為乙個有序的陣列,從兩個陣列的開始比較,小的取出來放在temp陣列中,指標加一,一直到兩個陣列都遍歷完畢即完成了組合。
二、快速排序
我先說一下快速排序的核心:引用白話經典演算法的作者所說的就是填坑以實現分治。也就是每輪排序,先選定乙個基準數,排序的結果是實現比它大的數放在前面(基準數的左邊),比它小的數放在後面(基準數的右邊)。一輪排序過後實現基於此基準數的排序。假設i和j分別指向陣列的頭和尾。那麼一輪排序的過程如下:
a.設定基準數為a[i](此時a[i]相當於被挖了個坑)
b.j從後往前遍歷,當a[j]
c.i從前往後遍歷,當a[i]>x時,a[j]=a[i];j位置被填,同時i位置被挖。此時先執行個j--;如果i==j時,a[i]=x,本輪迴圈結束。否則繼續執行b,c兩步,直到i==j時,a[i]=x;
當執行完一遍快排後,基於基準數左右兩邊是分治的。左邊的小於基準數,右邊的大於基準數。再對左右兩邊做快排,遞迴呼叫最終就實現了排序的功能。
其實快排的思想說的直白點:也即基於基準數,小的放前面(基準數的左邊)、大的放右邊(基準數的右邊)。通過不斷遞迴、不斷選取基準數使得陣列有序。
三、堆排序
用於排序的堆分為:大根堆和小根堆。它們都是二叉堆,其實也就是類似二叉樹的另乙個說法。我們進行堆排序的第一步:將陣列堆化。陣列堆化也即將陣列化為大根堆或者小根堆。陣列可以看成乙個二叉堆,但必須經過堆化才能化為標準的大根堆或者小根堆。二叉堆的葉子節點一般認為是合乎規定的子堆。只需從(n/2-1)到0進行堆化即可。也即不斷調整(n/2-1)到0的結點的值,以使堆為標準的大根堆或者小根堆。然後進行堆排序的第二步:取根節點的值,將堆進行重新調整。然後不斷遞迴。標準大根堆的根節點即是最大的數,取出根節點的數,將陣列最後乙個數與之互換,即完成了將最大的數放置於最後。每次取根節點並與堆最後的數互換,這樣因為每次取的結點都是剩餘中最大的,這樣就完成了乙個可序化的排列了。
其實堆排序簡單來說:就是化為標準堆結構(大根堆或者小根堆),再不斷取根節點放在陣列最後,然後調整堆為標準堆,進而不斷迴圈最終得到的就是排好序的陣列。
面試排序演算法個人總結
總結了很久的排序演算法,自己測試了很多次,一直寫在筆記本上,還是怕弄丟了,還是貼到部落格上面來吧 氣泡排序 交換排序 氣泡排序 param arr public static void bubblesort long arr if exchange 0 插入排序 直接插入排序 param arr p...
經典排序演算法個人總結
應用場景 求乙個問題最優解,且該問題可分解為若干子問題,子問題還能再分為子問題且每個子問題都存在最優解 整個問題的最優解依賴於各個子問題的最優解 從上向下分析問題,從下向上求解問題 解決最小問題開始,並且把已經解決的子問題的最優解儲存下來 面試題通常儲存在一維或二維陣列裡 然後把子問題最優解組合起來...
排序演算法總結
1 直接插入排序 1 穩定性 穩定 2 適用情況 待排記錄規模較小,或者記錄已經基本有序 2 希爾排序 1 穩定性 不穩定 2 特點 希爾排序的執行時間依賴於增量序列,它的效率比直接插入排序有較大的改進。3 氣泡排序 1 穩定性 穩定 2 特點 當待排記錄基本有序是,氣泡排序是不錯的選擇 但由於氣泡...