堆其實就是一顆完全二叉樹(若設二叉樹的深度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊),定義為:具有n個元素的序列(h1,h2,…hn),當且僅當滿足(hi>=h2i,hi>=h2i+1)或(hi<=h2i,hi<=2i+1) (i=1,2,…,n/2)時稱之為堆,堆主要包括大根堆和小根堆。
大頂堆(大根堆):
任何一棵子樹的最大值都是這個子樹的頭部;
堆頂元素(即第乙個元素)為最大項,並且(hi>=h2i,hi>=h2i+1)
小頂堆(小根堆):
任何一棵子樹的最小值都是這個子樹的頭部;
堆頂元素為最小項,並且(hi<=h2i,hi<=2i+1)
方法:
先給出乙個序列:[4,6,5,8,9]
**流程:
這個過程我們也叫做堆結構的heapinsert(乙個新結點加入到堆中依次向上比對的過程)看具體的**:
for
(int i =
0; i < arr.length; i++
)
i=index
public
static
void
heapinsert
(int
arr,
int index)
堆結構的heapify的過程:
當我們形成乙個大頂堆時,當堆中乙個資料突然發生變化(變小)時,會有可能使得大頂堆不存在,得做下沉操作,heapify的過程就是使得該完全二叉樹重新變成大頂堆。
就是將當前的結點與其左右子節點進行比較,大的進行交換
public
static
void
heapify
(int
arr,
int index,
int size)
//將兩個數進行交換
swap
(arr, largest, index)
;//此時將子樹的最大值的下標賦值給index、index來到子樹的位置繼續做下沉操作
//直到最後越界位置停止該操作
index = largest;
left = index *2+
1;}}
第一步:這就是堆排序的主要**,先將無序的序列通過heapinsert的過程變成大頂堆;
第二步:把最後乙個數後堆頂的數進行交換,size-1;
第三步:通過heapify的過程重新構建大根堆;
接下來的過程就是最後乙個數後堆頂的數進行比較,size-1,再次重新構成大根堆,以此類推最終陣列的順序就是從小 到大的乙個排序。
public
static
void
heapsort
(int
arr)
for(
int i =
0; i < arr.length; i++
)int size = arr.length;
//把第一位數也就是大頂堆的頂點和最後一位數進行交換,因為是大頂堆,頂點最大
//然後將size=size-1的操作
swap
(arr,0,
--size)
;while
(size >0)
}
全部**
package com.whw.tree;
public
class
heapsort
//給定乙個陣列,我們先要實現的就是根據陣列形成大根堆,我們用heapinsert
for(
int i =
0; i < nums.length; i++
)//我們是如何根據大根堆來完成排序的的呢,我們分析大根堆的根節點是當前陣列中的最大的值
//我們將根節點的數字與葉子結點的最後乙個值進行交換,並將size-1
int size = nums.length;
swap
(nums,0,
--size)
;while
(size >0)
}//這邊實現乙個堆排序,要實現這個結構我們先要的就是分析堆這個結構
/**1、首先我們要做的就是將乙個陣列轉換成乙個大根堆;
* 將陣列轉換成大根堆的思想很簡單我們拿到乙個陣列,及當前插入結點的下標
* */
//構建大根堆,先得有乙個heapinsert,j就是將陣列裡面的數字乙個個的插入到大根堆
//大根堆要求的是其任何一棵子樹的最大值就是這棵子樹的頭部
/** *
* @param nums
* @param index 當前插入結點的下標
*/public
static
void
heapinsert
(int
nums,
int index)
}// heapify的過程指的是在乙個已經形成的大根堆裡面,突然某乙個頭結點的數字發生變化,能調整回大根堆的過程
/** *
* @param nums
* @param index 改變量字的下標
* @param size 指的是當前的大根堆的乙個大小,來控制其的界限
*/public
static
void
heapify
(int
nums,
int index,
int size)
swap
(nums,largest,index)
;//繼續向下搜尋,比較大小,直到全部的比較完,此時會發生越界
index = largest;
left = index*2+
1;}}
//交換函式
private
static
void
swap
(int
nums,
int i,
int j)
}
堆與堆排序
二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 當父結點的鍵值總是大於或等於任何乙個子節點的鍵值時為最大堆。當父結點的鍵值總是小於或等於任何乙個子節點的鍵值時...
堆與堆排序
堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。堆排序是就地排序,輔助空間為o 1 它是不穩定的排序方法。排序的穩定性是指如果在排序的序列中,存在前後相同的兩個元素的話,排序前 和排序後他們的相對位置不發生變化 先說說什麼是堆,堆通常是乙個可以被看做一棵樹的陣列物...
堆與堆排序
堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。學習堆排序前,先講解下什麼是資料結構中的二叉堆。二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都是乙個二叉堆...