博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅵ
阅读量:5329 次
发布时间:2019-06-14

本文共 3309 字,大约阅读时间需要 11 分钟。

· 学后心得体会与部分习题实现

 

心得体会:

 

曾经只是了解了优先队列的基本性质,并会调用C++ STL库中的priority_queue以及 java.util.PriorityQueue<E>中的优先队列封装类,但是没有看过源码,也并不曾知道实现方法用到了堆结构。

 

优先队列通过堆进行插入元素和删除最小元素的两种高效操作来维护元素集合,每个操作的时间都为对数级(logN)。堆结构及其操作符合优先队列的全部特点,另附有高效率,用来描述与实现优先队列再合适不过。

 

在学习过程中,在对于堆结构众多操作的巧妙操作中,令我印象深刻的是两种操作:swim() 和 sink()操作,即对于新元素或者删除最大(或最小)根节点后的新根的上浮和下沉操作(有些教材上称为上滤和下滤操作。其命名个人YY的含义是:由于swim() 和sink() 操作是用在insert() 和 delMax() 两个方法中的子方法,用于过滤二叉堆,使其重构成完全二叉树结构。)。

 

该方法的效率证明可以参看《Introduction to Algorithm》(《算法导论》)中的 6.2 维护堆的性质:

 

通过对优先队列的学习,自己用Java实现了一下。并可以用以下这个个人编写的二叉堆的实现,完成《Algorithms 4th Edition》中的2.4.1和2.4.6。

 

 

1 import java.math.*; 2  3 public class MaxPQ
> { 4 private Key[] pq; 5 private int N = 0; 6 7 @SuppressWarnings("unchecked") 8 public MaxPQ(int maxN) { 9 pq = (Key[]) new Comparable[maxN + 1];10 }11 12 public boolean isEmpty() {13 return N == 0;14 }15 16 public int size() {17 return N;18 }19 20 public void insert(Key v) {21 pq[++N] = v; swim(N);22 }23 24 private void exch(int i, int j) {25 Key t = pq[i]; pq[i] = pq[j]; pq[j] = t;26 }27 28 public Key delMax() {29 Key max = pq[1];30 exch(1, N--);31 pq[N + 1] = null;32 sink(1);33 return max;34 }35 36 private boolean less(int i, int j) {37 return pq[i].compareTo(pq[j]) < 0;38 }39 40 private void swim(int k) {41 while(k > 1 && less(k / 2, k)) {42 exch(k / 2, k);43 k =k / 2;44 }45 }46 47 private void sink(int k) {48 while(2 * k <= N) {49 int j = 2 * k;50 if(j < N && less(j, j + 1)) j++;51 if(!less(k, j)) break;52 exch(k , j);53 k = j;54 }55 }56 57 public void prtPQ() {58 for(int i = 1; i <= N; i++) {59 System.out.print(pq[i] + " ");60 }61 System.out.println();62 }63 }

 

 

以下是对应部分题目实现(只给出Main部分):

 

1 import java.math.*; 2 import java.util.*; 3  4 public class Main { 5     public static void main(String[] args) { 6         MaxPQ
PQ = new MaxPQ
(1000); 7 String op = "PRIO*R**I*T*Y***QUE***U*E"; 8 int cnt = 0; 9 for(int i = 0; i < op.length(); i++) {10 if(op.charAt(i) == '*') {11 System.out.println(++cnt + ". Max is " + PQ.delMax());12 } else {13 PQ.insert(op.charAt(i));14 }15 }16 17 }18 }
2.4.1

 

运行结果:

 

 

 

1 import java.math.*; 2 import java.util.*; 3  4 public class Main { 5     public static void main(String[] args) { 6         MaxPQ
PQ = new MaxPQ
(1000); 7 String op = "PRIO*R**I*T*Y***QUE***U*E"; 8 int cnt = 0; 9 for(int i = 0; i < op.length(); i++) {10 if(op.charAt(i) == '*') {11 PQ.delMax();12 } else {13 PQ.insert(op.charAt(i));14 }15 System.out.print(++cnt + ". ");16 PQ.prtPQ();17 }18 }19 }
2.4.6

 

 

运行结果:


 

至此,对于优先队列的学习告一段落。笔者一直相信唯 有坚持者才能把算法学的精通,所以算法的学习之路好会坚持下去。一直用luc的文章 来激励自己,相信自己终有一天,能达到自己理想的高度。如此才不后悔。

 


 

转载于:https://www.cnblogs.com/Destiny-Gem/p/3800952.html

你可能感兴趣的文章
nuget使用
查看>>
关于一类最小割图的建法
查看>>
Django---自定义admin组件思维导图
查看>>
输入一个链表,反转链表后,输出链表的所有元素。
查看>>
转如何用九条命令在一分钟内检查Linux服务器性能?
查看>>
win7下 go语言开发环境搭建(64bit)
查看>>
JavaScript权威指南--客户端存储
查看>>
leetcode Group Anagrams
查看>>
关于set和setsecure方法
查看>>
Django:(博客系统)使用使用mysql数据&创建post/category/tag实体,并同步到数据中...
查看>>
前端常用CSS小技巧
查看>>
LCT
查看>>
[POJ2406&POJ1961]用KMP解决字符串的循环问题两例
查看>>
传值调用与引用调用
查看>>
JZOJ 5922. sequence
查看>>
Object-C Xcode 编译提示 note: please rebuild precompiled header ZWYLPrefixHeader
查看>>
使用InternetGetConnectedState判断本地网络状态(C#举例)
查看>>
ios 读取通讯录数据
查看>>
Shapley值的一个应用
查看>>
遍历父视图上的button
查看>>