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

心得体会:

曾经只是了解了优先队列的基本性质,并会调用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)-Ⅵ的更多相关文章

  1. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅶ(延伸:堆排序的实现)

    2.4.5 堆排序 我们可以把任意优先队列变成一种排序方法.将所有元素插入一个查找最小元素的有限队列,然后再重复调用删除最小元素的操作来将他们按顺序删去.用无序数组实现的优先队列这么做相当于进行一次插 ...

  2. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅴ

    命题Q.对于一个含有N个元素的基于堆叠优先队列,插入元素操作只需要不超过(lgN + 1)次比较,删除最大元素的操作需要不超过2lgN次比较. 证明.由命题P可知,两种操作都需要在根节点和堆底之间移动 ...

  3. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅰ

    许多应用程序都需要处理有序的元素,但不一定要求他们全部有序,或者是不一定要以此就将他们排序.很多情况下我们会手机一些元素,处理当前键值最大的元素,然后再收集更多的元素,再处理当前键值最大的元素.如此这 ...

  4. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅳ

    2.4.4 堆的算法 我们用长度为 N + 1的私有数组pq[]来表示一个大小为N的堆,我们不会使用pq[0],堆元素放在pq[1]至pq[N]中.在排序算法中,我们只能通过私有辅助函数less()和 ...

  5. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅲ

    2.4.3 堆的定义 数据结构二叉堆能够很好地实现优先队列的基本操作.在二叉堆的数组中,每个元素都要保证大于等于另两个特定位置的元素.相应地,这些位置的元素又至少要大于等于数组中的两个元素,以此类推. ...

  6. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅱ

    2.4.2初级实现 我们知道,基础数据结构是实现优先队列的起点.我们可以是使用有序或无序的数组或链表.在队列较小时,大量使用两种主要操作之一时,或是所操作元素的顺序已知时,它们十分有用.因为这些实现相 ...

  7. C++Primer 4th edition读书笔记-第二章

    1 变量的定义用于为变量分配存储空间,还可以为变量指定初始值.在一个程序中,变量有且只有一个定义.声明用于向程序表明变量的名字和类型.定义也是声明:当定义变量时,我们声明了它的类型和名字.可以通过使用 ...

  8. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅳ

    3.1.4 无序链表中的顺序查找 符号表中使用的数据结构的一个简单选择是链表,每个结点存储一个键值对,如以下代码所示.get()的实现即为遍历链表,用equals()方法比较需被查找的键和每个节点中的 ...

  9. 《C++ Primer 4th》读书笔记 序

    注:本系列读书笔记是博主写作于两三年前的,所以是基于<C++ Primer>第四版的,目前该书已更新至第五版,第五版是基于C++11标准的,貌似更新挺多的.博主今年应届硕士毕业,如若过阵子 ...

随机推荐

  1. phpcms:三、头部包含

    1‘标题:{if isset($SEO['title']) && !empty($SEO['title'])}{$SEO['title']}{/if}{$SEO['site_title ...

  2. poj 2100 Graveyard Design(尺取法)

    Description King George has recently decided that he would like to have a new design for the royal g ...

  3. [Qt] fontawesome图标

    fontawesome图标 fontawesome是一个图标的集合,里面有好多的图标,使用起来也还是非常方便的. 图标信息可以到官网去查:http://fontawesome.io/cheatshee ...

  4. pyqt托盘例子

    # -*- coding: cp936 -*- #!/usr/bin/env python # -*- coding:utf-8 -*- from PyQt4 import QtCore, QtGui ...

  5. (转载)XML Tutorial for iOS: How To Read and Write XML Documents with GDataXML

    In my recent post on How To Choose the Best XML Parser for Your iPhone Project, Saliom from the comm ...

  6. 【精品】Android游戏类源码大集合

    Android自定义效果——随机抽奖 一个模拟抽奖的效果,用户设定若干个选项,添加之后,就可以通过程序,来帮助随机选择其中一项出来.这个类似超市里面那种指针转盘抽奖,run之后是一个动态效果图,初始快 ...

  7. RMAN常用备份恢复命令汇总

    RMAN命令 1.独立命令  RMAN>shutdown immediate  RMAN>startup  RMAN>backup format 'd:\backup\%d_%s.b ...

  8. ERROR 1 (HY000): Can't create/write to file '/tmp/#sql_909_0.MYI' (Errcode: 13)

    mysql> desc tablename; ERROR 1 (HY000): Can't create/write to file '/tmp/#sql_909_0.MYI' (Errcode ...

  9. 不安装开发环境,查看logcat日志

    #公司的测试终于想到要看 android 的日志.安装开发环境太麻烦了,这里有个简单的办法. 我把\sdk\platform-tools目录中,文件名以"adb"开头的三个文件打包 ...

  10. linux for循环

    一定要记得写后面的分号:http://www.runoob.com/linux/linux-shell-variable.html 这个页面的课程的循环教程是有问题的 for color in yel ...