日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构-堆的实现

發布時間:2025/3/20 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构-堆的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
堆本質是一棵二叉樹,其中所有的元素都可以按全序語義進行比較。用 堆來進行存儲需要符合以下規則:
1.元素可比較性:數據集中的元素可以進行比較,就是要實現Comparable接口;。
2.節點最大/最小性:每個節點的元素必須大于或小于該節點的孩子節點的元素

3.堆是一棵完全二叉樹

堆有兩種:最大堆和最小堆。

最小堆中每個節點的優先級小于或者等于它的子節點;最大堆則相反,每個節點的優先級都大于或者等于它的子節點。

如下圖:



本文只著重講最大堆吧,最小堆是一樣的。

堆的大小是提前知道的,在java集合中堆是通過ArrayList數組實現的:

1.根節點位置:根節點的數據總是在數組的位置[0]
2.節點的父節點位置:假設一個非根節點的數據在數組中的位置[i],那么它的父節點總是在位置[(i-1)/2]
3.節點的孩子節點位置:假設一個節點的數據在數組中的位置為[i],那么它的孩子(如果有)總是在下面的這兩個位置:左孩子在[2*i+1],右孩子在[2*i+2]

在堆中主要是插入和刪除節點的操作,這兩種操作無論是哪一種,完成之后都還是一個堆,操作時要進行堆的調整,使其是個新堆。

一,添加一個新節點:(不斷地和父節點比較

插入的思路是這樣的:當插入一個元素時,先將這個元素插入到隊列尾,然后將這個新插入的元素和它的父節點進行優先權的比較,如果比父節點的優先權要大,則和父節點呼喚位置,然后再和新的父節比較,直到比新的父節點優先權小為止


二,刪除一個節點(不斷比較左右孩子節點大小,大的上移

從堆中刪除優先權最大的元素的思路是將隊列尾的元素值賦給根節點,隊列為賦 值為null。然后檢查新的根節點的元素優先權是否比左右子節點的元素的優先權大,如果 比左右子節點的元素的優先權小,就交換位置,重復這個過程,直到秩序正常。



heap.java實現

//最大堆 import java.util.ArrayList; public class Heap<E extends Comparable>{private ArrayList<E> list=new ArrayList<E>();//用數組實現堆public Heap(){}public Heap(E[] objects){for(int i=0;i<objects.length;i++){add(objects[i]);}}public void add(E newObject){//添加一個元素list.add(newObject);int currentIndex=list.size()-1;while(currentIndex>0){int parentIndex=(currentIndex-1)/2;//找到該結點的父結點if(list.get(currentIndex).compareTo(list.get(parentIndex))>0){//與父節點比較//如果當前結點的值大于父結點就交換位置E temp=list.get(currentIndex);list.set(currentIndex, list.get(parentIndex));list.set(parentIndex, temp); }elsebreak;currentIndex=parentIndex;} }public E remove(){//刪除并返回根結點,堆的特點是移除了根結點后還是堆if(list.size()==0) return null;E removeObject=list.get(0);list.set(0, list.get(list.size()-1));//把最后一個結點放在根結點的位置list.remove(list.size()-1);int currentIndex=0;while(currentIndex<list.size()){int leftChildIndex=2*currentIndex+1;int rightChildIndex=2*currentIndex+2;//左右孩子結點的坐標if(leftChildIndex>=list.size())break;//比較左右孩子的值,使maxIndex指向值大的結點int maxIndex=leftChildIndex;if(rightChildIndex<list.size()){if(list.get(maxIndex).compareTo(list.get(rightChildIndex))<0){maxIndex=rightChildIndex;}}//如果當前結點的值小于其左右孩子中的大的值,就交換兩個結點if(list.get(currentIndex).compareTo(list.get(maxIndex))<0){E temp=list.get(maxIndex);list.set(maxIndex, list.get(currentIndex));list.set(currentIndex, temp);currentIndex=maxIndex;}elsebreak;}return removeObject; }public int getSize(){return list.size();}}
















總結

以上是生活随笔為你收集整理的数据结构-堆的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。