堆排序 最大堆 選擇排序的一種

2021-08-27 16:13:28 字數 2269 閱讀 3720

堆排序只要理解了原理其實並不難,我在寫這個演算法時,按照理解一次性就成功了☺

1.首先應該明確的是堆(二叉堆)是一顆完全二叉樹;

因為二叉堆是一顆完全二叉樹,所以可以用陣列來儲存堆中的每乙個元素,而且可以通過某個節點在陣列中的下標(i)很方便的找到其左右孩子節點的下標以及其父親節點的下標,如下圖所示:

由上圖還可以推出乙個非常有用的性質:

假設我們用陣列arr來儲存二叉堆,則:

最後乙個葉子節點的索引為arr.length-1

最後乙個非葉子節點的索引為:(arr.length-1-1)/2

2.大根堆和小根堆:

大根堆:堆中所有父節點都大於其左右子節點的堆

小根堆:堆中所有父節點都小於其左右子節點的堆

或者按照下面的方式進行定義[ ]

堆的定義:n個關鍵字序列array[0,…,n-1],當且僅當滿足下列要求:(0 <= i <= (n-1)/2)

① array[i] <= array[2i + 1] 且 array[i] <= array[2i + 2]; 稱為小根堆;

② array[i] >= array[2i + 1] 且 array[i] >= array[2i + 2]; 稱為大根堆;

3.由陣列生成大根堆(該過程又叫heapify)

n個節點的完全二叉樹array[0,…,n-1],最後乙個節點n-1是第(n-1-1)/2個節點的孩子。對第(n-1-1)/2個節點為根的子樹調整,使該子樹成為堆。

對於大根堆,調整方法為:若【根節點的關鍵字】小於【左右子女中關鍵字較大者】,則交換。

之後向前依次對各節點((n-1-1)/2 - 1)~ 0為根的子樹進行調整,看該節點值是否大於其左右子節點的值,若不是,將左右子節點中較大值與之交換,交換後可能會破壞下一級堆,於是繼續採用上述方法構建下一級的堆,直到以該節點為根的子樹構成堆為止。

反覆利用上述調整堆的方法建堆,直到根節點。

4.大根堆排序的原理

①將存放在array[0,…,n-1]中的n個元素建成初始堆;

②將堆頂元素與堆底元素進行交換,則序列的最大值即已放到正確的位置;

③但此時堆被破壞,將堆頂元素向下調整使其繼續保持大根堆的性質,再重複第②③步,直到堆中僅剩下乙個元素為止。

package com.nrsc.sort;

public

class

heapsort

;heapsort

(arr)

; system.out.

println

("排序後:");

for(

int i : arr)

}private

static

void

heapsort

(int

arr)

}/**

* 建立初始最大堆

* * @param arr

*/private

static

void

buildmaxheap

(int

arr)

}/**

* 調整堆中的節點使其滿足最大堆

* * @param arr

* @param i

* @param length

*/private

static

void

adjustdowntoup

(int

arr,

int i,

int length)

// 如果右子節點大於父節點和左子節點中的最大值,則將最大值下標改為右子節點的

if(right < length && arr[right]

> arr[largest]

)// 如果最大值不是父節點,而是左子節點或右子節點中的乙個

// 就需要將其與父節點進行對換

if(i != largest)

}/**

* 進行陣列中元素的交換

* * @param arr

* @param i

* @param largest

*/private

static

void

swap

(int

arr,

int i,

int largest)

}

最大堆 排序

解除安裝最前面,下面的所有討論都是基於二叉堆 一 什麼是堆 堆是乙個陣列結構,可以看著為一顆完全二叉樹,把這顆完全二叉樹按層從上到下,每層從左至右編序號,每個序號所對應的元素即為陣列中該序號的元素 該樹出最後一層以外每一層都排滿,最後一層從左至右,先左孩子再右孩子排列,如果有父節點沒有排滿孩子 無孩...

最大堆排序

其實堆排序就是對二叉樹的一種操作,使得二叉樹的左右孩子 節點都小於父節點。我使用的是陣列的實現方式,parent i return i 2 i的父節點下標,left i return 2 i i的左子節點 right i return 2 i 1 i的右子節點.以上均為陣列元素的標號位置,在訪問元素...

最大堆實現堆排序

堆排序 這裡使用的是最大堆 思想 1 將當前的堆轉換成最大堆 從最大的非葉子結點開始,1 判斷根結點和左右結點的大小交換相互的位置,使得該子樹成為最大堆,每次交換成功後就繼續往該結點的子結點去重複 1 操作,直到根結點後再去下乙個非葉子結點,直到根結點 2 轉成最大堆後,每次就將第乙個結點互最後乙個...