1 package org.example.algorithm.datastruct;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Comparator;
  5 import java.util.List;
  6 
  7 public class Heap<T> {
  8 
  9     private final Comparator<T> comparator;
 10 
 11     private List<T> keys = new ArrayList<>();
 12 
 13     public Heap() {
 14         comparator = null;
 15     }
 16 
 17     public Heap(Comparator<T> comparator) {
 18         this.comparator = comparator;
 19     }
 20 
 21     public Heap(List<T> keys) {
 22         comparator = null;
 23         this.keys.addAll(keys);
 24         buildMaxHeap();
 25     }
 26 
 27     public Heap(List<T> keys, Comparator<T> comparator) {
 28         this.comparator = comparator;
 29         this.keys.addAll(keys);
 30         buildMaxHeap();
 31     }
 32 
 33     public T top() {
 34         return keys.get(0);
 35     }
 36 
 37     public T extract() {
 38         if (keys.isEmpty())
 39             return null;
 40         T max = keys.get(0);
 41         T last = keys.remove(keys.size() - 1);
 42         if (!keys.isEmpty()) {
 43             keys.set(0, last);
 44         }
 45         maxHeapify(0);
 46         return max;
 47     }
 48 
 49     public void insert(T key) {
 50         if (key == null)
 51             throw new NullPointerException();
 52         if (keys.isEmpty()) {
 53             keys.add(key);
 54         } else {
 55             T last = keys.get(keys.size() - 1);
 56             keys.add(compare(last, key) < 0 ? last : key);
 57         }
 58         increaseKey(keys.size() - 1, key);
 59     }
 60 
 61     private static int parent(int index) {
 62         return (index - 1) >> 1;
 63     }
 64 
 65     private static int left(int index) {
 66         return (index << 1) + 1;
 67     }
 68 
 69     private static int right(int index) {
 70         return (index + 1) << 1;
 71     }
 72 
 73     private void maxHeapify(int index) {
 74         int left = left(index);
 75         int right = right(index);
 76         int largest = index;
 77         if (left < keys.size() && compare(keys.get(left), keys.get(largest)) > 0)
 78             largest = left;
 79         if (right < keys.size() && compare(keys.get(right), keys.get(largest)) > 0)
 80             largest = right;
 81         if (largest != index) {
 82             swap(largest, index);
 83             maxHeapify(largest);
 84         }
 85     }
 86 
 87     private void buildMaxHeap() {
 88         int n = (keys.size() - 1) >> 1;
 89         for (int i = n; i >= 0; i--) {
 90             maxHeapify(i);
 91         }
 92     }
 93 
 94     private void increaseKey(int index, T key) {
 95         if (key == null || compare(key, keys.get(index)) < 0)
 96             throw new RuntimeException("New key is smaller than current key.");
 97         keys.set(index, key);
 98         while (index > 0 && compare(keys.get(parent(index)), keys.get(index)) < 0) {
 99             swap(index, parent(index));
100             index = parent(index);
101         }
102     }
103 
104     @SuppressWarnings("unchecked")
105     private int compare(T key1, T key2) {
106         return comparator != null ? comparator.compare(key1, key2) :
107                 ((Comparable<T>)key1).compareTo(key2);
108     }
109 
110     private void swap(int index1, int index2) {
111         T temp = keys.get(index1);
112         keys.set(index1, keys.get(index2));
113         keys.set(index2, temp);
114     }
115 }

 

posted @ 2023-12-11 10:29  张时雨  阅读(16)  评论(0)    收藏  举报