• 二项堆


      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 }
  • 相关阅读:
    Hadoop的三大组件 内容
    常用的linux命令
    shell学习心得
    liunx学习心得。
    随机数
    HADOOP框架
    Shell学习心得
    linux学习心得
    jquery解决随机点餐系统重复问题
    在码云上git push时报错,出现error: failed to push some refs to 'https://gitee.com/lipengyangzuishuai/gitstudy.git'的解决办法
  • 原文地址:https://www.cnblogs.com/rilley/p/2584805.html
Copyright © 2020-2023  润新知