二项堆

  1 public class BinaryHeap<E extends Comparable<? super E>> 
  2 {
  3     
  4     public static void main(String[] args)
  5     {
  6         Integer[] array = {0, 12, 90, 1, 85, 12, 3, 13, 49,
  7             55, 10, 3, 31, 97, 19, 93, 41, 55, 56, 82, 2};
  8         
  9         BinaryHeap<Integer> heap = new BinaryHeap<Integer>();
 10         
 11         for (int i = 0; i < array.length; i++) {
 12             heap.insert(array[i]);
 13         }
 14         
 15         heap.traversal(heap.head);
 16         System.out.println();
 17         
 18         Integer item = (Integer) heap.find(new Integer(55));
 19         
 20         if (item == null)
 21             System.out.println("节点不存在");
 22         else 
 23             System.out.println("要找的节点为" + item.toString());
 24         
 25         System.out.println(heap.findMinNode().value);
 26         
 27         heap.traversal();
 28         heap.delete(new Integer(31), new Integer(-Integer.MIN_VALUE));
 29         System.out.println();
 30         heap.traversal();
 31     }
 32     
 33     
 34     HeapNode head = null;
 35     
 36     /*
 37      * 查询最小关键字节点
 38      * 由于二项堆中每个二项树都遵循最小堆性质,
 39      * 从heap节点依次遍历其兄弟节点,找出最小关键字节点
 40      */
 41     private HeapNode findMinNode()
 42     {
 43         if (head == null) return null;
 44         
 45         HeapNode node = head, min = head;
 46         
 47         while (node != null) {
 48             int compare = min.value.compareTo(node.value); 
 49             if (compare > 0) min = node;
 50             node = node.sibling;
 51         }
 52         return min;
 53     }
 54     
 55     /*
 56      * 插入节点
 57      */
 58     public void insert(E value)
 59     {
 60         if (value == null) return;
 61         
 62         HeapNode node = new HeapNode(value);
 63         BinaryHeap<E> bh = new BinaryHeap<E>();
 64         bh.head = node;
 65         union(bh);
 66     }
 67     
 68     /*
 69      * 合并节点
 70      */
 71     public void merge(BinaryHeap<E> heap)
 72     {
 73         HeapNode node;
 74         HeapNode head1 = this.head;
 75         HeapNode head2 = heap.head;
 76         
 77         // 确定head
 78         if (head1.degree < head2.degree) {
 79             node = head1;
 80             head1 = head.sibling;
 81         }
 82         else {
 83             this.head = head2;
 84             node = head2;
 85             head2 = head2.sibling;
 86         }
 87         
 88         // 归并合并二项堆
 89         while (head1 != null && head2 != null) {
 90             if (head1.degree < head2.degree) {
 91                 node.sibling = head1;
 92                 node = head1;
 93                 head1 = head1.sibling;
 94             }
 95             else {
 96                 node.sibling = head2;
 97                 node = head2;
 98                 head2 = head2.sibling;
 99             }
100         }
101         
102         node.sibling = (head1 == null) ? head2 : head1;
103     }
104     
105     /*
106      * 查找节点
107      */
108     private HeapNode find(E value, HeapNode node)
109     {
110         if (node == null) return null;
111         if (value.compareTo(node.value) == 0) return node;
112         
113         HeapNode node1 = find(value, node.sibling);
114         HeapNode node2 = find(value, node.child);
115         
116         if (node1 != null) return node1;
117         if (node2 != null) return node2;
118         return null;
119     }
120     
121     /*
122      * 查询节点
123      */
124     public E find(E value)
125     {
126         HeapNode node = find(value, head);
127         if (node == null) return null;
128         return node.value;
129     }
130     
131     /*
132      * 合并二项堆
133      * 将this和heap合并成一个新二项堆
134      */
135     private void union(BinaryHeap<E> heap)
136     {
137         if (heap.head == null) return;
138         if (this.head == null) { 
139             this.head = heap.head;
140             return;
141         }
142         
143         merge(heap);
144         
145         HeapNode prev = null;
146         HeapNode node = this.head;
147         HeapNode next = node.sibling;
148         /*
149          * 情况1 degree[x] != degree[next], x为B-k书的根,next为B-l书的根且l > k
150          * 动作  将指针移向表中下一个位置
151          * 
152          * 情况2 degree[x] = degree[next] = degree[sibling[next]]
153          * 动作  将指针移向表中下一个位置,下一次迭代将执行情况3或4,将第二和第三个根联合起来
154          * 
155          * 情况3 x为具有相同度数的两个根中的第一个发生时
156          *      degree[x] = degree[next] != degree[sibling[next]]
157          * 动作  value[x] <= value[next] 将next连接到x上作为x的左孩子
158          * 
159          * 情况4 x为具有相同度数的两个根中的第一个发生时
160          *      degree[x] = degree[next] != degree[sibling[next]]
161          * 动作  value[x] > value[next] 将x连接到next上作为next的左孩子
162          */
163         while (next != null) {
164             if ((node.degree != next.degree) || 
165                     (next.sibling != null && next.sibling.degree == node.degree)) {
166                 prev = node;
167                 node = next;
168             }
169             else if (node.value.compareTo(next.value) <= 0) {
170                 node.sibling = next.sibling;
171                 link(next, node);
172             }
173             else {
174                 if (prev == null) {
175                     this.head = next;
176                 }
177                 else {
178                     prev.sibling = next;
179                 }
180                 link(node, next);
181                 node = next;
182             }
183             next = node.sibling;
184         }
185     }
186     
187     public void delete(E value, E min)
188     {
189         HeapNode node = find(value, head);
190         if (node == null) return;
191         decreaseKey(value, min);
192         extractMin();
193     }
194     
195     /*
196      * 减小某解点的值
197      */
198     private void decreaseKey(E source, E target)
199     {
200         HeapNode node = find(source, head);
201         if (node == null) return;
202         node.value = target;
203         HeapNode parent = node.parent;
204         
205         while (parent != null && 
206             node.value.compareTo(parent.value) < 0) 
207         {
208             // 交换当前结点与父节点的值
209             E temp = node.value;
210             node.value = parent.value;
211             parent.value = temp;
212             
213             node = parent;
214             parent = parent.parent;
215         }
216     }
217     
218     /*
219      * 抽取关键字最小的节点
220      */
221     private void extractMin()
222     {
223         HeapNode min = findMinNode();
224         HeapNode minPrev = head;
225         
226         // 独立最小值所在二项数
227         if (min != head) {
228             while (minPrev.sibling != min) {
229                 minPrev = minPrev.sibling;
230             }
231             minPrev.sibling = min.sibling;
232         }
233         else {
234             head = head.sibling;
235         }
236         min.sibling = null;
237         
238         BinaryHeap<E> bh = new BinaryHeap();
239         
240         // 将min与子节点分离
241         HeapNode child = min.child;
242         child.parent = min.child = null;
243         
244         // 
245         HeapNode prev, node, next;
246         prev = child;
247         node = child.sibling;
248         prev.sibling = null;
249         
250         while (node != null) {
251             next = node.sibling;
252             node.parent = null;
253             node.sibling = prev;
254             prev = node;
255             node = next;
256         }
257         
258         bh.head = prev;
259         
260         // 将分离出来的二项堆与原来的合并
261         union(bh);
262     }
263     
264     /*
265      * 连接两个节点
266      */
267     private void link(HeapNode big, HeapNode small)
268     {
269         big.parent = small;
270         big.sibling = small.child;
271         small.child = big;
272         small.degree++;
273     }
274     
275     public void traversal(HeapNode node)
276     {
277         if (node == null) return;
278         System.out.print(node.value + ",");
279         traversal(node.sibling);
280         traversal(node.child);
281     }
282     
283     /*
284      * 遍历二项堆
285      */
286     public void traversal()
287     {
288         traversal(head);
289     }
290     
291     
292     class HeapNode
293     {
294         private HeapNode parent;
295         
296         private HeapNode sibling;
297         
298         private HeapNode child;
299         
300         private E value;
301         
302         private int degree = 0;
303 
304         
305         public HeapNode(E value)
306         {
307             this.value = value;
308         }
309     }
310 }
原文地址:https://www.cnblogs.com/rilley/p/2584805.html