zoukankan      html  css  js  c++  java
  • java实现堆

    java实现小顶堆,堆是优先队列的底层数据结构

    import com.google.common.collect.Lists;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    /**
     * 如果根节点所在下标是0,则父节点下标i,左孩子下标2i+1,右孩子2i+2
     * 如果根节点所在下标是1,则父节点下标i,左孩子下标2i,右孩子2i+1
     * 因为我们用的是ArrayList,所有根节点下标为0
     *
     * @param <T>
     */
    @Data
    @NoArgsConstructor
    public class MHeap<T extends Comparable<T>> {
        private final int capacity = 100;
        private List<T> items = new ArrayList<T>(capacity);
    
        @Override
        public String toString() {
            return "MHeap{" +
                    "items=" + items +
                    '}';
        }
    
        /**
         * 传入list构建堆
         *
         * @param items
         */
        public MHeap(List<T> items) {
            for (T item : items) {
                insert(item);
            }
    
        }
    
        public boolean isEmpty() {
            return items.isEmpty();
        }
    
    
    
    
    
        public void insert(T data) {
            items.add(data);
            floatUp(data);
    
        }
    
        /**
         * 上浮:指定元素与父节点做比较,小于父节点就上浮,
         * 一直上浮到它应在的位置
         */
        private void floatUp(T data) {
            int child = items.size() - 1;
            int parent = (child - 1) / 2;
            //小则上浮
            while (data.compareTo(items.get(parent)) < 0) {
                items.set(child, items.get(parent));
                child = parent;
                parent = parent / 2;
                if (child == 0) {
                    break;
                }
            }
            items.set(child, data);
        }
    
        /**
         * 1.先拿到最小值,暂存等待返回
         * 2.获取最后一个节点last的数据e
         * 3.e数据放在根节点可能不一定最小,对比根的孩子节点逐级下沉,让根最小的孩子上浮
         * 4.把原来最后的节点last删掉
         *
         * @return
         */
        public T pop() {
            T t = items.get(0);
            int last = items.size() - 1;
            T e = items.get(last);
            sinkDown( e);
            items.remove(last);
            return t;
        }
        /**
         * 下沉:根节点下沉到它应该的位置
         */
        private void sinkDown(T data) {
            int size = items.size();
            //当前根
            int parent = 0;
            //当前根的左孩子
            int child = parent * 2 + 1;
            //循环条件是还没有越界
            while (child < size) {
                //判断根是否有右孩子,假如右孩子更小,拿到更小的孩子,等待与根节点对比
                if (child + 1 < size && items.get(child + 1).compareTo(items.get(child)) < 0) {
                    child = child + 1;
                }
                //父节点小于最小的子节点,则不用动了
                if (data.compareTo(items.get(child)) < 0) {
                    break;
                }
                //父节点大于最小的孩子,则最小的孩子上浮到根节点
                items.set(parent, items.get(child));
                parent = child;
                child = parent * 2 + 1;
            }
            items.set(parent, data);
        }
    
        public static void main(String[] args) {
            List<Integer> ints = Lists.newArrayList();
            Random rand = new Random();
    
            for (int i = 10; i > 0; i--) {
                int i1 = rand.nextInt(100);
                ints.add(i1);
            }
            System.out.println(ints);
    
            MHeap<Integer> m = new MHeap<>(ints);
            while (!m.isEmpty()) {
                System.out.println(m.pop());
            }
        }
    }
  • 相关阅读:
    函数调用本质
    互联网协议入门
    iOS开发系列-Block本质篇
    iOS组件化开发-CocoaPods简介
    版本控制-Git
    iOS开发系列-NSDate
    iOS开发系列-线程同步技术
    Python 抓取网页gb2312乱码问题
    常用正则表达式
    Java 命名规范
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15385244.html
Copyright © 2011-2022 走看看