《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标准的,貌似更新挺多的.博主今年应届硕士毕业,如若过阵子 ...
随机推荐
- Java高级软件工程师面试考纲
如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构.算法.网络.操作系统等知识.因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对 ...
- 为人们服务的asp.net 验证控件
ASP.NET是微软推出的WEB开发工具,他有很强大的功能,今天看视频讲到验证控件这一部分,真的感受到了微软全心全意为人民服务了.越来越佩服微软了,人家都设计出来了,咱们一定要会用才可以啊,不然太…. ...
- c/c++ 复习基础要点01-const指针、指针函数 函数指针、new/delete与malloc/free区别与联系
1. 引用本身是有指针实现的:引用为只读指针 例子: int d=123; int& e=d; //引用 int * const e=d; //只读指针,e指向d,不可修改e指 ...
- IE常见的CSS的BUG(一)
2011年6月,我毕业了.2012年我接触了CSS,本以为会好过些能赚点钱了,可谁知,Internet Explorer(下称IE),这个前端工程师的噩梦浏览器让我不再那么好过了.各种出现在IE身上的 ...
- Fantageek翻译系列之《使用Autolayout显示变化高度的UITableViewCell》
这篇博客主要在于,解释如何通过仅仅使用Autolayout很很少的代码,显示高度不同的Cell.虽然标题说的是TableView,但是CollectionView同样适合.但是,这种方法只使用iOS7 ...
- DevExpress控件-GridControl根据条件改变单元格/行颜色--转载
DevExpress控件-数据控件GridControl,有时我们需要根据特定条件改变符合条件的行或者单元格颜色达到突出显示目的,现在动起鼠标跟我一起操作吧,对的,要达到这个目的您甚至都不用动键盘. ...
- KindEditor放在包含模版页的页面里不显示解决方案
由于用了母版页,内容页服务器控件(是服务器控件哦)的id会被重写,我这里运行中查看源代码,控件的id变成了“ContentPlaceHolder1_content1”. <asp:TextBox ...
- iOS在MRC工程环境下下使用ARC的方法
- 记一次令人发狂的 bug Eclipse 开不开 tomcat 7.0
改项目,结果发现以前的项目也出了问题,就删除了系统用户下面workplace里的文件夹,结果,eclipse被清空,重新添加项目,发现一堆bug; 最让我崩溃的是,用tomcat 7.0跑项目,反复出 ...
- redis基础操作
/** * redis的Java客户端Jedis测试验证 * * @author */ public class Test { /** * 非切片客户端链接 */ private Jedis jedi ...