08荷蘭國旗問題**
將小於大於區域進行劃分,當數值小於則將資料放到左邊,l+1,當資料大於則將資料放到右邊r,同時將r-1.
由於荷蘭問題較為簡單,因此在這裡不再編寫**。
public
static
void
quicksort
(int
arr)
quicksort
(arr,
0,arr.length-1)
;}public
static
void
quicksort
(int
arr,
int l,
int r)
}public
static
int[
]partition
(int
arr,
int l,
int r)
else
if(arr[l]
>arr[r]
)else
}swap
(arr,more,r)
;return
newint
;}public
static
void
swap
(int
arr,
int i,
int j)
改進後的快排是將陣列的最後乙個數值按照該數值去劃分,將小於x部分的範圍和大於x的範圍劃分出來,之後再進行快速排序。相較而言,再去快速排序的範圍縮小,所以時間複雜度相同,但是實際運算的時候會速度快一些。
最好的情況複雜度為t(n)=2t(n/2)+o(n),但是如果資料狀況特別差,則複雜度會很高。
整個陣列隨機選擇乙個數,將其放到最後,再進行快速排列,因此最後的複雜度表示式是乙個含有概率的表示式。
隨機快排是最常用的排序,非常重要
隨機快排的複雜度為乙個期望複雜度:o(n*logn),額外空間複雜度為o(logn)在這裡插入**片
**如上所示。
在工程上改寫成非遞迴版本,工程上一般不允許遞迴函式
堆的結構是完全二叉樹,堆可以用陣列來實現,將陣列理解為完全二叉樹。
如果一棵具有n個結點的深度為k的二叉樹,它的每乙個結點都與深度為k的滿二叉樹中編號為1~n的結點一一對應,這棵二叉樹稱為完全二叉樹。
將二叉樹轉化為陣列,0為父節點,奇數為左節點,偶數為又節點。
大根堆:(完全二叉樹)任何一顆子樹的最大值都是這個子樹的頭部。
小根堆:任何一顆子樹的最小值都是這個子樹的頭部。
建立大根堆
如何將乙個陣列轉化為大根堆:根據完全二叉樹和陣列對應的特點,從陣列最左邊父節點開始依次調整,對於不符合的節點進行交換,從而將普通陣列轉換為大根堆。(若子節點的數值大於父節點,則需要將父節點和子節點進行轉換,依次遞迴)
1.i-1已經形成大根堆
2.第i位置跟父位置進行比較,如果大於父位置則進行交換
3.若小於父位置,則不需要處理。
在完全二叉樹中加入乙個新的節點加入的複雜度為logn,
建立大根堆的過程的複雜度為將n-1個節點依次加入的過程,最後收斂於o(n)
在建立大根堆的過程中,為heapinsert,在堆中某個資料發生改變之後需要調整的時候,為heapify,堆資料可以增加也可以減少,堆資料增加可以使用heapinsert。
堆在系統中是優先順序佇列,調整代價較小,只需要承擔logn的複雜度就可以完成,非常重要
演算法流程:
1.首先建立兩個堆,乙個大根堆,乙個小根堆
2.將第乙個資料防入大根堆,第二個資料到來之後跟大根堆中的資料進行比較,如果資料小於大根堆中的根,則放入大根堆中,此時大根堆中會有兩個資料,而小根堆中沒有資料。
3.如果出現大根堆和小根堆中的數目不相等,相差2,則將資料較多的堆的父節點彈出,放入資料較少的資料堆中當父節點。堆頂需要刪掉則可以執行將堆底最後的資料跟堆頂換位,將堆的資料heapsize減少,之後再進行heapify,則重新調整為大根堆。
經過上述三個步驟,則可以實現大根堆中的資料小於小根堆中的資料,中位數的資料只會從大根堆和小根堆的父節點中選出,隨時進入資料,則可以隨時調整,複雜度較低。
左神演算法學習日記 堆(二)
include include include include include include include includeusing namespace std class project project const project p push進堆時用到了拷貝建構函式,雖然不寫也無所謂 pro...
左神演算法筆記01
對數器異或工具 一些其它的位運算子的操作 簡單理解為 將乙個演算法的所有操作拆成基本操作 常數時間完成的操作 後,計算出操作次數和操作時間 可視為1 的乘積,即操作次數之和。在考慮最差情況時用o 來表示時間複雜度,取最高項來表示。如o n o logn 對n個數進行排列,則最差要進行1 2 3 n ...
左神演算法筆記03
可以是函式遞迴,也可以是迴圈實現。將大的陣列對半分為兩個陣列,每個陣列排好序後再合併為大的陣列。如果使用迴圈實現,要提防整形溢位 應用 最小和問題,若陣列的左邊的乙個數比右邊的某乙個數小,在返回結果加上自身的大小 public static intprocess int arr,int l,int ...