Java集合9——PriorityQueue实现类

PriorityQueue简介

优先级队列继承AbstractQueue,实现了java.ioSerializable。

1,成员变量

 // 默认容量 
    private static final int DEFAULT_INITIAL_CAPACITY = 11;

    /**
     * 数组存储,数组存储的是堆内元素
     */
    private transient Object[] queue;

    /**
     * 优先队列内元素个数
     */
    private int size = 0;

    /**
     * 比较器
     */
    private final Comparator<? super E> comparator;

    /**
     *修改次数
     */
    private transient int modCount = 0;

2,我们来看看它的构造函数

 /**
     * 创建一个具有默认初始容量(11),根据其自然顺序对其元素PriorityQueue。
     */
    public PriorityQueue() {
        this(DEFAULT_INITIAL_CAPACITY, null);
    }

    /**
     * 创建与根据其自然顺序对其元素指定的初始容量创建一个PriorityQueue。
     */
    public PriorityQueue(int initialCapacity) {
        this(initialCapacity, null);
    }

    /**
     * 创建与根据指定的比较器对其元素指定的初始容量创建一个PriorityQueue。
     */
    public PriorityQueue(int initialCapacity,
                         Comparator<? super E> comparator) {
        // Note: This restriction of at least one is not actually needed,
        // but continues for 1.5 compatibility
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        this.queue = new Object[initialCapacity];
        this.comparator = comparator;
    }

    /**
     * 创建一个包含指定优先级队列中的元素一个PriorityQueue
     */
    @SuppressWarnings("unchecked")
    public PriorityQueue(Collection<? extends E> c) {
        if (c instanceof SortedSet<?>) {
            SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
            this.comparator = (Comparator<? super E>) ss.comparator();
            initElementsFromCollection(ss);
        }
        else if (c instanceof PriorityQueue<?>) {
            PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
            this.comparator = (Comparator<? super E>) pq.comparator();
            initFromPriorityQueue(pq);
        }
        else {
            this.comparator = null;
            initFromCollection(c);
        }
    }

    /**
     * 创建一个包含指定有序set的元素一个PriorityQueue.
     */
    @SuppressWarnings("unchecked")
    public PriorityQueue(PriorityQueue<? extends E> c) {
        this.comparator = (Comparator<? super E>) c.comparator();
        initFromPriorityQueue(c);
    }

    @SuppressWarnings("unchecked")
    public PriorityQueue(SortedSet<? extends E> c) {
        this.comparator = (Comparator<? super E>) c.comparator();
        initElementsFromCollection(c);
    }

它是基于小根堆(父节点小于子节点)这个数据结构实现的。这里牵涉到了大小关系,元素大小的评判可以通过元素本身的自然顺序,也可以通过构造时传入的比较器

现在我们给它添加一个元素

add():添加一个元素

添加一个元素,就会破坏原有小根堆的形式,所以我们要进行调整。siftUp()方法就是对它进行调整

我们也可以通过构造函数来用优先级队列构造一个大根堆。比较的时候我们可以传入我们想要的对象

2,remove():删除一个元素

删除一个元素后要对它重新进行调整。

接下来看一个运用优先级队列的小例子

找100000个数字中重复最少的十个数

public class Test10 {
	public static void main(String[] args) {
		/**
		 * 初始化100000个数字
		 */
		Random random = new Random();
		ArrayList<Integer> number = new ArrayList<Integer>(100000);
		for(int i = 0; i < 100000;i++){
			number.add(random.nextInt(100000));
		}
		
		minTen(number);
	}
	/**
	 * 100000个数字 里重复最少的十个数
	 * 使用小根堆
	 * @param number 
	 */
	private static void minTen(ArrayList<Integer> number) {
		// TODO Auto-generated method stub
		/**
		 * 将数和重复次数分别当作键和值存入hashmap中
		 */
		HashMap<Integer, Integer> hashmap = new  HashMap<Integer, Integer>();
		for(int i = 0;i < number.size();i++){
			if(!hashmap.containsKey(number.get(i))){
				hashmap.put(number.get(i), 0);
			}else{
				hashmap.put(number.get(i), hashmap.get(number.get(i))+1);
			}
		}
		/**
		 * 重写Comparator里的compare()方法  将优先级队列比较的东西变为比较value值
		 */
		PriorityQueue<Map.Entry<Integer, Integer>> priorityQueue = new PriorityQueue<Map.Entry<Integer, Integer>>(new Comparator<Map.Entry<Integer, Integer>>(){

			@Override
			public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
				// TODO Auto-generated method stub
				return o2.getValue()-o1.getValue();
			}
			
		});
		/**
		 * 遍历hashmap 构造大根堆 o2.getValue()-o1.getValue() 完成需要的是个最小的数
		 */
		Iterator<Map.Entry<Integer, Integer>> iterator = hashmap.entrySet().iterator();
		while(iterator.hasNext()){
			Map.Entry<Integer, Integer> next = iterator.next();
			if(priorityQueue.size() == 10){
				if(next.getValue() < priorityQueue.peek().getValue()){
					priorityQueue.remove();
					priorityQueue.add(next);
				}	
			}else{
				priorityQueue.add(next);
			}
		}
		
		while(priorityQueue.size() > 0){
			System.out.printf(priorityQueue.remove().getKey()+" ");
		}
		
	}
}

猜你喜欢

转载自blog.csdn.net/qq_37937537/article/details/81158536
今日推荐