堆結構與堆排序

2021-10-01 07:24:40 字數 3358 閱讀 2831

堆其實就是一顆完全二叉樹(若設二叉樹的深度為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 每個結點的左子樹和右子樹都是乙個二叉堆...