《数据结构与算法分析:C语言描述》复习——第五章“堆”——二叉堆

2014.06.15 22:14

简介:

  堆是一种非常实用的数据结构,其中以二叉堆最为常用。二叉堆可以看作一棵完全二叉树,每个节点的键值都大于(小于)其子节点,但左右孩子之间不需要有序。我们关心的通常只有堆顶的元素,而整个堆则被封装起来,保存在一个数组中。

图示:

  下图是一个最大堆:

  

实现:

  优先队列是STL中最常用的工具之一,许多算法的优化都要利用堆,使用的工具就是优先队列。STL中的优先队列通过仿函数来定义比较算法,此处我偷懒用了“<”运算符。关于使用仿函数的好处,我之后如果有时间深入学习STL的话,再写博文分析吧。

  1 // My implementation for priority queue using binary heap.
  2 #include <iostream>
  3 #include <string>
  4 #include <vector>
  5 using namespace std;
  6
  7 template <class T>
  8 class PriorityQueue {
  9 public:
 10     PriorityQueue() {
 11         m_data.push_back(0);
 12     }
 13
 14     PriorityQueue(const vector<T> &data) {
 15         m_data.push_back(0);
 16         for (size_t i = 0; i < data.size(); ++i) {
 17             m_data.push_back(data[i]);
 18         }
 19         _makeHeap();
 20     }
 21
 22     bool empty() {
 23         return m_data.size() == 1;
 24     }
 25
 26     size_t size() {
 27         return m_data.size() - 1;
 28     }
 29
 30     T top() {
 31         return m_data[1];
 32     }
 33
 34     void push(const T &val) {
 35         m_data.push_back(val);
 36
 37         int n = size();
 38         int i = n;
 39
 40         while (i > 1) {
 41             if (m_data[i / 2] < m_data[i]) {
 42                 _swap(m_data[i / 2], m_data[i]);
 43                 i /= 2;
 44             } else {
 45                 break;
 46             }
 47         }
 48     }
 49
 50     void pop() {
 51         int n = size();
 52         m_data[1] = m_data[n];
 53         m_data.pop_back();
 54         --n;
 55
 56         int i = 1;
 57         T max_val;
 58         while (i * 2 <= n) {
 59             max_val = i * 2 == n ? m_data[i * 2] : _max(m_data[i * 2], m_data[i * 2 + 1]);
 60             if (m_data[i] < max_val) {
 61                 if (max_val == m_data[i * 2] || i * 2 == n) {
 62                     _swap(m_data[i], m_data[i * 2]);
 63                     i = i * 2;
 64                 } else {
 65                     _swap(m_data[i], m_data[i * 2 + 1]);
 66                     i = i * 2 + 1;
 67                 }
 68             } else {
 69                 break;
 70             }
 71         }
 72     }
 73
 74     void clear() {
 75         m_data.resize(1);
 76     }
 77
 78     ~PriorityQueue() {
 79         m_data.clear();
 80     }
 81 private:
 82     vector<T> m_data;
 83
 84     T _max(const T &x, const T &y) {
 85         return x > y ? x : y;
 86     }
 87
 88     void _swap(T &x, T &y) {
 89         T tmp;
 90
 91         tmp = x;
 92         x = y;
 93         y = tmp;
 94     }
 95
 96     void _makeHeap() {
 97         int n = size();
 98         int i, j;
 99         T max_val;
100
101         for (j = n / 2; j >= 1; --j) {
102             i = j;
103             while (i * 2 <= n) {
104                 max_val = i * 2 == n ? m_data[i * 2] : _max(m_data[i * 2], m_data[i * 2 + 1]);
105                 if (m_data[i] < max_val) {
106                     if (max_val == m_data[i * 2] || i * 2 == n) {
107                         _swap(m_data[i], m_data[i * 2]);
108                         i = i * 2;
109                     } else {
110                         _swap(m_data[i], m_data[i * 2 + 1]);
111                         i = i * 2 + 1;
112                     }
113                 } else {
114                     break;
115                 }
116             }
117         }
118
119         n = size();
120         cout << ‘[‘;
121         for (int i = 1; i <= n; ++i) {
122             cout << m_data[i] << ‘ ‘;
123         }
124         cout << ‘]‘ << endl;
125     }
126 };
127
128 int main()
129 {
130     vector<int> v;
131     v.push_back(1);
132     v.push_back(2);
133     v.push_back(3);
134     v.push_back(4);
135     v.push_back(5);
136     v.push_back(6);
137     v.push_back(7);
138     v.push_back(8);
139     PriorityQueue<int> pq(v);
140     string s;
141     int n;
142
143     while (cin >> s) {
144         if (s == "push") {
145             cin >> n;
146             pq.push(n);
147         } else if (s == "pop") {
148             pq.pop();
149         } else if (s == "top") {
150             cout << pq.top() << endl;
151         } else if (s == "end") {
152             while (!pq.empty()) {
153                 pq.pop();
154             }
155             break;
156         }
157     }
158
159     return 0;
160 }

《数据结构与算法分析:C语言描述》复习——第五章“堆”——二叉堆

时间: 2024-12-22 16:30:35

《数据结构与算法分析:C语言描述》复习——第五章“堆”——二叉堆的相关文章

《数据结构与算法分析—C语言描述》pdf

下载地址:网盘下载 内容简介 编辑 <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行时间分析的基础上考查了一些高级数据结构,从历史的角度和近年的进展对数据结构的活跃领域进行了简要的概括.由于<数据结构与算法分析:C语言描述(原书第2版)>选材新颖,方法实用,题例丰富,取舍得当.<数据结构与算法分析:C语言描述(原书第2版)>的目的是培养学生良好的程序设计技巧和熟练的算

数据结构与算法分析 c语言描述 pdf 高清下载

网盘下载:数据结构与算法分析 c语言描述 pdf 高清下载 – 易分享电子书PDF资源网 作者: [美] Mark Allen Weiss 出版社: 机械工业出版社 副标题: C语言描述 原作名: Data Structures and Algorithm Analysis in C:Second Edition 译者: 冯舜玺 出版年: 2004-1-1 页数: 391 定价: 35.00元 装帧: 平装 内容简介 · · · · · · 本书是<Data Structures and Alg

数据结构与算法分析_Java语言描述(第2版)高清版pdf免费下载

下载地址:网盘下载 备用地址:网盘下载 内容简介编辑“数据结构”是计算机专业的基础与核心课程之一,Java是现今一种热门的语言.本书在编写过程中特别考虑到了面向对象程序设计(OOP)的思想与Java语言的特性.它不是从基于另一种程序设计语言的数据结构教材简单地“改编”而来的,因此在数据结构的实现上更加“地道”地运用了Java语言,并且自始至终强调以面向对象的方式来思考.分析和解决问题.本书是为数据结构入门课程(通常课号是CS-2)而编写的教材.作者Frank Carrano在编写过程自始至终特别

数据结构与算法分析_Java语言描述(第2版)pdf

下载地址:网盘下载 本书是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计). 随着计算机速度的不断增加和功能的日益强大,人们对有效编程和算法分析的要求也不断增长.本书将算法分析与最有效率的Java程序的开发有机地结合起来,深入分析每种算法,并细致讲解精心构造程序的方法,内容全面.缜密严格. 第3版的主要更新如下: ? 第4章包含AVL树删除算法的实现. ? 第5章进行了全面修订和扩充,现在包含两种较

《数据结构与算法分析Java语言描述》PDF文件免费下载

图书简介: 本书是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计). 随着计算机速度的不断增加和功能的日益强大,人们对有效编程和算法分析的要求也不断增长.本书把算法分析与最有效率的Java程序的开发有机地结合起来,深入分析每种算法,内容全面.缜密严格,并细致讲解精心构造程序的方法. 图书目录部分截图: 结语:总结 数据结构与算法分析需要这份PDF文档的朋友,欢迎加Q群:219571750,免费领取,

《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes

表.栈和队列是最简单和最基本的三种数据结构.基本上,每一个有意义的程序都将明晰地至少使用一种这样的数据结构,比如栈在程序中总是要间接地用到,不管你在程序中是否做了生命. 本章学习重点: 理解抽象数据类型(ADT)的概念 学习如何对表进行有效的操作 熟悉栈ADT及其在实现递归方面的应用 熟悉队列ADT及其在操作系统和算法设计中的应用 ADT 抽象数据类型(abstract data type)是一个操作的集合,是数学的抽象,在ADT中不涉及如何实现操作的集合,这可以看作是模块化设计的扩充. 对于每

《数据结构与算法分析 C语言描述》读书笔记——分治算法

书中用求解最大子序列和的方式介绍了分治算法(divide-and-conquer) 分治算法是一种相对快速的算法 运行时间为O(logN) 最大子序列和的问题如下: 给出一组整数 A1  A2 … AN 求∑jk=i Ak 若所有整数均为负 则最大子序列和为0 e.g. 输入-2, 11,-4, 13, -5, -2 输出20(A2到A4) 分治算法就如同字面描述的一样 先分再治 分 指的是将问题分为两部分几乎相同的子问题 进行递归求解 治 指的是将 分 的解通过简单的手段合并 得到最终解 对于

【数据结构与算法分析——C语言描述】练习1.1——选择问题

本部分内容来自http://www.cnblogs.com/mingc,笔者在此只用于整理学习. 问题描述:编写一个程序解决选择问题.令k=N/2.画出表格显示你的程序对于N为不同值时的运行时间. 理解:设有一组N个数确定其中第k个最大者,称选择问题(selection problem) 思路:读入前k个数到临时数组tmp(并按降序排列).然后逐个读取后续数字X,当X大于第k个数时,将其加入数组tmp(并按降序排列).最后返回位置k-1上的值 #include <stdio.h> #inclu

《数据结构与算法分析——C语言描述》ADT实现(NO.01) : 栈(Stack)

这次的数据结构是一种特殊的线性表:栈(Stack) 栈的特点是后入先出(LIFO),可见的只有栈顶的一个元素. 栈在程序中的地位非常重要,其中最重要的应用就是函数的调用.每次函数调用时都会创建该函数的一个“活动记录”( Activation Record ,或称作“帧”( Frame ))压入运行时堆栈中,用于保存函数的参数,返回值,返回指令地址,返回活动记录地址,局部变量等内容.当然,在高级语言中我们不需要手动完成这一工作,学习汇编语言时会体会到其真正过程. 下面给出笔者对于堆栈的两种实现.首