左神演算法筆記(二) 快速排序,堆

2021-10-02 11:42:00 字數 2147 閱讀 9659

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 ...