二叉堆
一棵完全二叉樹,對於大頂堆來說,任何乙個結點都要大於等於它左右孩子結點,對於小頂堆,任何乙個結點都要小於等於它的左右孩子。
二叉堆與陣列的聯絡
二叉堆一般儲存在陣列中,有這樣的性質,如果我們把二叉堆按照從上到下,從左到右的順序依次存進陣列,如果 index 是某個結點的下標值,那麼它左右孩子結點的下標值分別是2*index+1
和2*index+2
,不信的筒子們可以嘗試寫到陣列中看看規律。我在陣列中怎麼知道這個下標的值是右結點還是左結點呢?我們減去 2 除以 2 除得盡就是右結點,否則是左結點,並且其父節點的下標也可以確定了。這個陣列儲存著這個二叉堆的所有資訊
二叉堆的增刪
二叉堆的新增和刪除,我們會把乙個結點新增到最下一層的最後面,然後與父節點比較,進而上浮或者不動;對於刪除來講,假如我們刪除某乙個中間結點,我們就需要用最尾部結點對刪掉的節點位置進行補位,補上之後,再對這個補位的結點和最小(大)的直接子結點比較,進而選擇下沉或不動
堆排序
我們利用二叉堆,上浮下沉的性質每次找到最大的結點上浮到頂端,然後我們再儲存到最後面,這樣就可以從小到大排序了!詳細的說堆排序就是先建立大頂堆或小頂堆,然後把這個堆根和最尾部交換位置,將除了尾部的繼續構成堆,這樣不斷迴圈就可以實現堆排序了
上浮還是下沉?
尾部新增結點時候是上浮操作,上浮比較簡單,因為孩子結點只有乙個雙親;刪除結點是下沉操作,下沉麻煩一點,因為乙個雙親結點有兩個孩子結點,下沉要比較兩個孩子
構建二叉堆
無序序列,非葉子結點開始往前遍歷,每次遍歷中,將該結點選擇性下沉,這樣遍歷完就構建起了乙個二叉堆
二叉堆的最後乙個非葉子節點怎麼求?
(arr.length-1-1)/2
思路
利用二叉堆的存入陣列的性質很容易實現堆排序,我們一起來寫一下吧
// 二叉堆尾部新增結點之後的自行調整
public
static
void
upadjust
(int
array)
array[childindex]
= temp;
}// 二叉堆刪掉結點之後的自行調整
public
static
void
downadjust
(int
array,
int parentindex,
int length)
// 如果父節點小於任何乙個孩子的值,直接跳出
if(temp <= array[childindex]
)break
;//無需真正交換,單向賦值即可
array[parentindex]
= array[childindex]
; parentindex = childindex;
childindex =
2* childindex +1;
} array[parentindex]
= temp;
}// 構造小頂堆
public
static
void
getheap
(int
array)
}// 堆排序(從大到小)
public
static
void
main
(string[
] args)
;upadjust
(array)
; system.out.
println
(arrays.
tostring
(array));
array =
newint
;buildheap
(array)
; system.out.
println
(arrays.
tostring
(array));
}
時間複雜度為 o(n*logn)
因為只用到有限的變數,並且是陣列就地排序,空間複雜度為 o(1)
堆排序一般來說是不穩定的排序演算法
排序 選擇排序 選擇排序 堆排序
寫在前面 上傳github交換排序選擇排序 堆排序 選擇排序 顧名思義,我們就可以猜到,它是原則合適的元素放到合適的位置 從圖中,我們可以得到 1.用第乙個元素,和其他所有的元素進行比較,找出最小的,然後進行交換 2.然後進行,資料的遞增 3.直到資料全部有序 void selectsort int...
選擇排序 堆排序
選擇排序 selection sort 是一種簡單直觀的排序演算法。它的工作原理是每一次從待排序的資料元素中選出最小 或最大 的乙個元素,存放在序列的起始位置,直到全部待排序的資料元素排完。選擇排序是不穩定的排序方法 比如序列 5,5,3 第一次就將第乙個 5 與 3 交換,導致第乙個5挪動到第二個...
選擇排序 堆排序
堆排序 堆排序分為兩個過程 1 將原來無序的數列,轉化成堆序列 建初識堆的過程 2 輸出堆頂元素並調整建新堆的過程 資料結構偽 typeof sqlist heaptype void heapadjuisti heaptype h,int s int m for i h.length i 1 i c...