《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅵ
· 学后心得体会与部分习题实现
心得体会:
曾经只是了解了优先队列的基本性质,并会调用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。
import java.math.*;
public class MaxPQ<Key extends Comparable<Key>> {
private Key[] pq;
private int N = 0;
@SuppressWarnings("unchecked")
public MaxPQ(int maxN) {
pq = (Key[]) new Comparable[maxN + 1];
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
public void insert(Key v) {
pq[++N] = v; swim(N);
}
private void exch(int i, int j) {
Key t = pq[i]; pq[i] = pq[j]; pq[j] = t;
}
public Key delMax() {
Key max = pq[1];
exch(1, N--);
pq[N + 1] = null;
sink(1);
return max;
}
private boolean less(int i, int j) {
return pq[i].compareTo(pq[j]) < 0;
}
private void swim(int k) {
while(k > 1 && less(k / 2, k)) {
exch(k / 2, k);
k =k / 2;
}
}
private void sink(int k) {
while(2 * k <= N) {
int j = 2 * k;
if(j < N && less(j, j + 1)) j++;
if(!less(k, j)) break;
exch(k , j);
k = j;
}
}
public void prtPQ() {
for(int i = 1; i <= N; i++) {
System.out.print(pq[i] + " ");
}
System.out.println();
}
}
以下是对应部分题目实现(只给出Main部分):
import java.math.*;
import java.util.*; public class Main {
public static void main(String[] args) {
MaxPQ<Character> PQ = new MaxPQ<Character>(1000);
String op = "PRIO*R**I*T*Y***QUE***U*E";
int cnt = 0;
for(int i = 0; i < op.length(); i++) {
if(op.charAt(i) == '*') {
System.out.println(++cnt + ". Max is " + PQ.delMax());
} else {
PQ.insert(op.charAt(i));
}
} }
}
2.4.1
运行结果:

import java.math.*;
import java.util.*; public class Main {
public static void main(String[] args) {
MaxPQ<Character> PQ = new MaxPQ<Character>(1000);
String op = "PRIO*R**I*T*Y***QUE***U*E";
int cnt = 0;
for(int i = 0; i < op.length(); i++) {
if(op.charAt(i) == '*') {
PQ.delMax();
} else {
PQ.insert(op.charAt(i));
}
System.out.print(++cnt + ". ");
PQ.prtPQ();
}
}
}
2.4.6
运行结果:


至此,对于优先队列的学习告一段落。笔者一直相信唯 有坚持者才能把算法学的精通,所以算法的学习之路好会坚持下去。一直用luc的文章 http://zh.lucida.me/blog/on- learning-algorithms/ 来激励自己,相信自己终有一天,能达到自己理想的高度。如此才不后悔。
《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅵ的更多相关文章
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅶ(延伸:堆排序的实现)
2.4.5 堆排序 我们可以把任意优先队列变成一种排序方法.将所有元素插入一个查找最小元素的有限队列,然后再重复调用删除最小元素的操作来将他们按顺序删去.用无序数组实现的优先队列这么做相当于进行一次插 ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅴ
命题Q.对于一个含有N个元素的基于堆叠优先队列,插入元素操作只需要不超过(lgN + 1)次比较,删除最大元素的操作需要不超过2lgN次比较. 证明.由命题P可知,两种操作都需要在根节点和堆底之间移动 ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅰ
许多应用程序都需要处理有序的元素,但不一定要求他们全部有序,或者是不一定要以此就将他们排序.很多情况下我们会手机一些元素,处理当前键值最大的元素,然后再收集更多的元素,再处理当前键值最大的元素.如此这 ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅳ
2.4.4 堆的算法 我们用长度为 N + 1的私有数组pq[]来表示一个大小为N的堆,我们不会使用pq[0],堆元素放在pq[1]至pq[N]中.在排序算法中,我们只能通过私有辅助函数less()和 ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅲ
2.4.3 堆的定义 数据结构二叉堆能够很好地实现优先队列的基本操作.在二叉堆的数组中,每个元素都要保证大于等于另两个特定位置的元素.相应地,这些位置的元素又至少要大于等于数组中的两个元素,以此类推. ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅱ
2.4.2初级实现 我们知道,基础数据结构是实现优先队列的起点.我们可以是使用有序或无序的数组或链表.在队列较小时,大量使用两种主要操作之一时,或是所操作元素的顺序已知时,它们十分有用.因为这些实现相 ...
- C++Primer 4th edition读书笔记-第二章
1 变量的定义用于为变量分配存储空间,还可以为变量指定初始值.在一个程序中,变量有且只有一个定义.声明用于向程序表明变量的名字和类型.定义也是声明:当定义变量时,我们声明了它的类型和名字.可以通过使用 ...
- 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅳ
3.1.4 无序链表中的顺序查找 符号表中使用的数据结构的一个简单选择是链表,每个结点存储一个键值对,如以下代码所示.get()的实现即为遍历链表,用equals()方法比较需被查找的键和每个节点中的 ...
- 《C++ Primer 4th》读书笔记 序
注:本系列读书笔记是博主写作于两三年前的,所以是基于<C++ Primer>第四版的,目前该书已更新至第五版,第五版是基于C++11标准的,貌似更新挺多的.博主今年应届硕士毕业,如若过阵子 ...
随机推荐
- [置顶] Oracle 11g R2 ASM:了解 Oracle ASM 基本概念
About Oracle ASM Instances About Oracle ASM Disk Groups About Mirroring and Failure Groups About Ora ...
- [转] Trie树详解及其应用
一.知识简介 最近在看字符串算法了,其中字典树.AC自动机和后缀树的应用是最广泛的了,下面将会重点介绍下这几个算法的应用. 字典树(Trie)可以保存一些字符串->值 ...
- 应用Observer接口实践Observer模式
原文:http://zhangjunhd.blog.51cto.com/113473/68949/ 在Java中通过Observable类和Observer接口实现了观察者模式.Observer对象是 ...
- JavaScript 精髓整理篇之一(对象篇)postby:http://zhutty.cnblogs.com
废话篇头: 由于工作关系,所以写博文的时间有那么点~~,其实是输入法太懒了,都是输入法的错~~ 这一系列的博客将总结所有关于JavaScript语言的精髓,适合0基础到大师级别人物阅读. <Ja ...
- Eclipse中Cannot find any provider supporting DES解决之道
原文出处:http://blog.csdn.net/darwinchina/article/details/12037999 异常: Caused by: java.security.NoSuchAl ...
- [Unit Testing] Based on input value, spyOn function
describe( 'Forgot Password: with username', ()=> { let dirElementInput; beforeEach( ()=> { // ...
- CSS background 属性 总结
CSS background 属性总结
- (转)div+css 布局经验 - 最简单的 = 最不变形的(原创技巧)
站酷几年了 一直饱受其恩泽 尤为感激 一直想奉献些什么 但是苦于水平 苦于奔波 今天静下心来 为大家奉献下 自己的div+css 经验 ,以下观点只代表 深海个人立场 希望为初学者提供一条" ...
- IOS网络开发实战(一)
1 局域网群聊软件 1.1 问题 UDP协议将独立的数据包从一台计算机传输到另外一台计算机,但是并不保证接受方能够接收到该数据包,也不保证接收方所接收到的数据和发送方所发送的数据在内容和顺序上是完 ...
- java运算
(一) 截图: 程序: import javax.swing.JOptionPane; public class Addition { public static void main (String ...