【CS61B学习笔记】Lecture 21 - Heaps and PQs

517 阅读2分钟

课程概要

  • 优先级队列
  • 总结

优先级队列(Priority Queue)

接口设计

 /** (Min) Priority Queue: Allowing tracking and removal of the
  * smallest item in a priority queue. */
public interface MinPQ<Item> {
	/** Adds the item to the priority queue. */
	public void add(Item x);
	/** Returns the smallest item in the priority queue. */
	public Item getSmallest();
	/** Removes the smallest item from the priority queue. */
	public Item removeSmallest();
	/** Returns the size of the priority queue. */
	public int size();
}

使用场景示例

  • 网络监听市民的聊天记录,找出最不和谐的 M 条对话 (Top K 问题)
  • 一般实现:创建包含所有对话的列表,并用 HarmoniousnessComparator 比较器来筛选出最不和谐的 M 条记录
public List<String> unharmoniousTexts(Sniffer sniffer, int M) {
    ArrayList<String> allMessages = new ArrayList<String>();
    for (Timer timer = new Timer(); timer.hours() < 24; ) {
        allMessages.add(sniffer.getNextMessage());
    }
    Comparator<String> cmptr = new HarmoniousnessComparator();
	Collections.sort(allMessages, cmptr, Collections.reverseOrder());
	
return allMessages.sublist(0, M);
}

上述方案内存占用 O(N),使用 MinPQ 内存占用 O(M), API 也更易使用

public List<String> unharmoniousTexts(Sniffer sniffer, int M) {
    Comparator<String> cmptr = new HarmoniousnessComparator();
    MinPQ<String> unharmoniousTexts = new HeapMinPQ<Transaction>(cmptr);
    for (Timer timer = new Timer(); timer.hours() < 24; ) {
        unharmoniousTexts.add(sniffer.getNextMessage());
       if (unharmoniousTexts.size() > M) 
          { unharmoniousTexts.removeSmallest(); }
    }
    ArrayList<String> textlist = new ArrayList<String>();
    while (unharmoniousTexts.size() > 0) {
          textlist.add(unharmoniousTexts.removeSmallest());
    }
    return textlist;
}

如何实现

  • 各种方案对比

MinPQ implementation compare.PNG

堆(Heap)

  • 上述方案 BST 可以工作,但是叶子节点维护和重复节点处理比较麻烦

  • 二叉最小堆定义:遵守完整性和最小堆规则

      最小堆:每个节点小于等于它的子节点
      完整性:只在最下层缺失元素,所有节点尽可能靠左(左满右不满)
    

binary-min-heap.PNG

堆的实现

  • 底层存储结构是数组,从小到大依次存储在数组中
  • 如果一个节点的位置为 k, 则它的父节点的位置为 [k/2], 它的两个子节点的位置分别为 2k 和 2k + 1

array index for heap elements.PNG

  • 添加元素:先暂时添加到堆尾,然后通过上浮算法上浮到合适的位置
  • 删除最小元素:将堆尾元素移动到根节点,然后通过下沉算法下沉到合适的位置
  • 动画演示[科学上网]

应用:

  • 堆排序

      1. 构造堆
      2. 得到堆顶元素,这个就是最大值
      3. 交换堆顶元素和数组中的最后一个元素,此时所有元素中的最大元素已经放到合适位置
      4. 对堆进行调整 ,重新让出了最后一个元素的剩余元素中的最大值放到堆顶
      5. 重复 2-4 这个步骤,知道堆中剩一个元素为止
    

总结

search ds-2016.PNG

search ds-2017.PNG

search ds - in Java.PNG

【参考】Lecture 21 - Heaps and PQs