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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

最大堆的Java实现

發布時間:2023/12/2 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最大堆的Java实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最大堆的解釋見:http://www.java3z.com/cwbwebhome/article/article1/1362.html?id=4745

這里是整理后的代碼:

import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List;import com.dm.core.structure.tupler.StrDoubleTuple;/*** 最大堆,用作優先隊列的TOPK查找<br>* 原理:每個節點的值都>=其左右孩子(如果有的話)值的完全二叉樹* * @author Anthony* @param <T>*/ public class MaxHeap<T> {/*** 堆數據*/private List<T> heap;/*** 堆數據的比較對象*/private Comparator<T> comparator;public MaxHeap(List<T> heap) {this(heap, new Comparator<T>() {@SuppressWarnings("unchecked")@Overridepublic int compare(T o1, T o2) {return ((Comparable<T>) o1).compareTo(o2);}});}public MaxHeap(List<T> heap, Comparator<T> comparator) {super();this.heap = heap;this.comparator = comparator;}/*** 向最大堆中插入元素,添加到數組的尾部,然后上升操作* * @param value*/public void insert(T value) {// 數組下標為0的位置不放元素if (heap.size() == 0)heap.add(null);heap.add(value);up(heap.size() - 1);}/*** 節點上升遞歸實現<br>* 由于新插入的數是在數組尾部,所以需要做上升操作,讓插入的數和父節點的值比較,當大于父節點的時候交換* * @param index*/private void up(int index) {// 注意堆是從下標為1開始,當index=1的時候,已經是根節點了if (index <= 1)return;int parent = index / 2; // 父節點T parentValue = heap.get(parent);T indexValue = heap.get(index);if (comparator.compare(parentValue, indexValue) < 0) {swap(parent, index);up(parent);}}/*** 節點上升非遞歸實現* * @param index*/@SuppressWarnings("unused")private void up2(int index) {int parent = 0;for (; index > 1; index /= 2) {parent = index / 2;T parentValue = heap.get(parent);T indexValue = heap.get(index);if (comparator.compare(parentValue, indexValue) < 0)swap(parent, index);}}/*** 交換a和b的位置* * @param a* @param b*/private void swap(int a, int b) {T temp = heap.get(a);heap.set(a, heap.get(b));heap.set(b, temp);}/*** 刪除堆中位置是index處的值<br>* 原理是:當刪除節點時,原來的位置就會出現一個孔,填充這個孔的方法就是,把最后的葉子賦給該孔,然后把該葉子刪除* * @param index*/public void delete(int index) {heap.set(index, heap.get(heap.size() - 1));down(index);heap.remove(heap.size() - 1);}/*** 節點下沉遞歸實現<br>* 刪除數據的時候,由于是用的尾部的數據(基本上是最小值)填充,所以需要做下沉操作* * @param index*/public void down(int index) {int n = heap.size() - 2; // 因為最后一個節點已經挪至index位置,所以已經是廢棄葉子節點,不再考慮int child = 2 * index;// 說明該節點沒有左右兒子節點了,那么無須下沉,直接返回if (child > n)return;// 如果左右兒子都存在,取值較大的那個兒子節點if (child < n&& comparator.compare(heap.get(child), heap.get(child + 1)) < 0)child++;// 如果該節點小于較大的那個兒子,那么下沉if (comparator.compare(heap.get(index), heap.get(child)) < 0) {swap(child, index);down(child);}}/*** 節點下沉非遞歸實現* * @param index*/public void down2(int index) {T temp = heap.get(index);int n = heap.size() - 2;int child = 0;for (; 2 * index <= n; index = child) {child = 2 * index;if (child < n&& comparator.compare(heap.get(child), heap.get(child + 1)) < 0)child++;if (comparator.compare(temp, heap.get(child)) < 0)swap(child, index);elsebreak;}}/*** 根據樹的性質建堆,樹節點前一半一定是分支節點,即有孩子的,所以我們從這里開始調整出初始堆* * @param heap*/public void adjust() {for (int i = heap.size() / 2; i > 0; i--)adjust(i, heap.size() - 1);}/*** 調整堆,使其滿足最大堆得定義<br>* 具體調整過程為: 從最后一個分支結點(n/2)開始,到根(1)為止,依次對每個分支結點進行調整(下沉)<br>* 以便形成以每個分支結點為根的堆,當最后對樹根結點進行調整后,整個樹就變成了一個堆* * @param i* @param n*/public void adjust(int i, int n) {int child = 0;for (; i <= n / 2;) {child = i * 2;if (child < n&& comparator.compare(heap.get(child), heap.get(child + 1)) < 0)child++;if (comparator.compare(heap.get(i), heap.get(child)) < 0) {swap(i, child);i = child; // 交換后,以child+1為根的子樹不一定滿足堆定義,所以從child處開始調整} elsebreak;}}/*** 堆排序,從尾部開始,將每個節點和根節點交換,然后調整節點之上的子堆*/public void sort() {for (int i = heap.size() - 1; i > 0; i--) {swap(1, i);adjust(1, i - 1);}}public static void main(String args[]) {List<Integer> array = new ArrayList<Integer>(Arrays.asList(null, 1, 2,5, 10, 3, 7, 11, 15, 17, 20, 9, 15, 8, 16));MaxHeap<Integer> mh = new MaxHeap<Integer>(array);mh.adjust();System.out.println("調整后的初始堆:" + array);mh.delete(8);System.out.println("刪除下標8之后的堆:" + array);mh.insert(99);System.out.println("添加值99之后的堆:" + array);mh.sort();System.out.println("排序后的堆:" + array);List<StrDoubleTuple> list = new ArrayList<StrDoubleTuple>();list.add(null);list.add(new StrDoubleTuple("a", 1.0));list.add(new StrDoubleTuple("a", 2.0));list.add(new StrDoubleTuple("a", 5.0));list.add(new StrDoubleTuple("a", 10.0));list.add(new StrDoubleTuple("a", 3.0));list.add(new StrDoubleTuple("a", 7.0));list.add(new StrDoubleTuple("a", 11.0));list.add(new StrDoubleTuple("a", 15.0));list.add(new StrDoubleTuple("a", 17.0));list.add(new StrDoubleTuple("a", 20.0));list.add(new StrDoubleTuple("a", 9.0));list.add(new StrDoubleTuple("b", 15.0));list.add(new StrDoubleTuple("a", 8.0));list.add(new StrDoubleTuple("a", 16.0));MaxHeap<StrDoubleTuple> mho = new MaxHeap<StrDoubleTuple>(list);mho.adjust();System.out.println("調整后的初始堆:" + list);mho.delete(8);System.out.println("刪除下標8之后的堆:" + list);mho.insert(new StrDoubleTuple("a", 99.0));System.out.println("添加值99之后的堆:" + list);mho.sort();System.out.println("排序后的堆:" + list);} }

  

?

轉載于:https://www.cnblogs.com/AnthonyViking/p/3623529.html

總結

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

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