資料結構(六) 堆

2021-08-21 11:20:43 字數 2846 閱讀 5016

二叉堆是基於完全二叉樹的;所謂完全二叉樹,就是每層的資料按照從左到右的方式儲存,即按照層序遍歷的順序儲存;每個節點都大於它的左孩子和右孩子,根節點為樹中最大的節點的堆為最大堆;相應的,每個節點都小於其左孩子和右孩子,根節點為最小節點的堆為最小堆;但是左右孩子的大小關係是不一定的;

很顯然,堆的實現可以是基於二叉樹的;但是更簡單的方法是基於陣列:

根節點的下標為1,對於下標為i的元素,它的左孩子的下標為2*i,右孩子下標為2*i+1,和基於二叉樹的實現方式相比較,乙個優勢是很容易找到節點的父節點,父節點的下標為i/2。這種下標之間的關係是依賴於完全二叉樹每層從左到右儲存的特點的;

下面是基於陣列的乙個最大堆的實現,提供了下面一些常見的操作:

詳細**如下:

package com.gby.heap;

import com.itheima.array.array;

public class maxheap>

public maxheap(int capacity)

public int getsize()

public boolean isempty()

public int parent(int index)

return (index-1)/2; }

public int leftchild(int index)

public int rightchild(int index)

public void add(e e)

private void siftup(int index) }

public e findmax()

return array.getfirst(); }

private void siftdown(int index)

while(leftchild(index)0)

array.swap(index, j);

index = j;

}} }

public e extractmax()

e maxele = array.getfirst();

array.set(0, array.removelast());

//通過下沉操作維護最大堆性質

siftdown(0);

return maxele; }

public e replace(e newele)

public void heapify(e arr)

}}

下面是實現思路:

1.最大堆中的資料要求父節點大於其左右孩子,所以堆中的元素必須是comparable的。

2.基於陣列實現,內部是乙個array型別的私有成員變數;這裡的array是之前資料結構(一)的部落格中封裝的動態陣列,可以自動改變容量,並提供了常用的方法;

3.提供無參和有參的構造方法

4.提供getsize()獲取堆的大小,提供isempty()判斷堆是否為空

根據之前的分析,提供上面三個方法找到乙個節點的父節點和左右孩子節點的下標;

向堆中新增元素時,預設先把元素放在陣列的最後,即下標為size-1的位置;相關判斷在array類中進行;

在新增乙個元素後,很有可能這個元素和它的父節點之間並不滿足父節點大於這個節點的條件;如果新新增的元素大於其父親節點,則我們把它和父節點下標的元素交換位置,在堆中表現為上浮到堆的上一層,成為siftup();上浮一次,很有可能它還是大於父節點,繼續上浮,直到它小於父節點或者到達完全二叉樹的根,即陣列下標為0的位置。

堆的設計是服務於優先佇列,出隊的為優先順序最大的或者最小的,對應堆中取出的元素應當是堆頂的元素,對應最大堆的extractmax()方法。

如果直接移除下標為0的元素,則其左右子樹需要整體移動,並產生新的根,操作複雜。乙個簡單的方法是用陣列的最後乙個元素替代下標為0的元素。很顯然,這樣做很容易會破壞根最大的性質; 那麼,如果根有新的根大於左右孩子,直接結束。否則和左右孩子中的最大值交換位置(如果有左右孩子);

replace方法是將堆頂的元素替換為使用者傳遞進去的元素,在替換後通過siftdown()維護堆的性質;

heapify方法是使用者傳遞乙個陣列,把它變成乙個堆;

一種方法是,迴圈遍歷arr,將每個元素通過add方法新增到乙個堆中;

另一種方法是,把該陣列看做乙個完全二叉樹,從第乙個非葉子節點到根節點進行遍歷,對每個遍歷到的節點進行下沉操作,整理成乙個堆,上面的**就是第二種方法;

以上就是堆這種資料結構的常見操作和實現。

資料結構 堆

最大堆 最小堆 堆的定義是 n個元素的序列,當且僅當滿足如下關係時被成為堆 1 ki k2i 且 ki k2i 1 或 2 ki k2i 且 ki k2i 1 i 1,2,n 2 當滿足 1 時,為最小堆,當滿足 2 時,為最大堆。若將此序列對應的一維陣列堪稱是乙個完全二叉樹,則2i和2i 1個節點...

資料結構 堆

資料結構 堆的操作和實現 當應用優先順序佇列或者進行堆排序時,一般利用堆來實現。堆是乙個完全 除最底層 外都是滿的 二叉樹,並滿足如下條件 1 根結點若有子樹,則子樹一定也是堆。2 根結點一定大於 或小於 子結點。因為要求堆必須是完全二叉樹,所以可以用線性的資料結構,比如陣列,來實現堆。利用陣列實現...

資料結構 堆

堆常用來實現優先佇列,在這種佇列中,待刪除的元素為優先順序最高 最低 的那個。在任何時候,任意優先元素都是可以插入到佇列中去的,是電腦科學中一類特殊的資料結構的統稱 最大 最小 堆是一棵每乙個節點的鍵值都不小於 大於 其孩子 如果存在 的鍵值的樹。大頂堆是一棵完全二叉樹,同時也是一棵最大樹。小頂堆是...