编程珠玑(2)第十四章学习笔记之“堆”
来源:互联网 发布:淘宝网外卖 编辑:程序博客网 时间:2024/05/16 12:27
本章主要介绍“堆”和“优先队列”数据结构的使用。
堆可分为大根堆和小根堆。堆是某个节点的值总是不大于(大根堆)或不小于(小根堆)其父节点的完全树。常见的堆有二叉堆和斐波那契堆,本章讲的是二叉堆。
由于二叉堆是完全二叉树,所以我们在建堆的时候可以考虑用C++中的vector来作为存储结构。
堆有两个比较重要的操作:插入和删除。插入时,我们一般将新插入的元素放在末尾,这时需要做向上调整;删除时一般是删除“根”节点元素,这时需要做向下调整,以确保堆的性质。
所谓优先队列是不同于先进先出的普通队列,而是每次从队列中取出具有最高优先权的元素。根据优先队列这一特点(每次取出最高优先权的元素),我们可以很自然地想到用堆来实现优先队列。补充一句:优先队列是一个非常有用的数据结构,在实际的编程中常常用到,在C++中有模板库,可以直接调用。
具体实现见代码:
#include<stdio.h>#include<vector>#include<stdexcept>using namespace std;//堆数据结构的实现(小根堆)template <typename T>class Heap{public:Heap(){}Heap(T elements[], int arraySize){for(int i=0; i<arraySize; i++){add(elements[i]);}}void add(T element){int currentIndex;v.push_back(element);currentIndex = v.size()-1;while(currentIndex > 0){int parentIndex = (currentIndex - 1) / 2;if(v[parentIndex] > v[currentIndex]){T temp = v[parentIndex];v[parentIndex] = v[currentIndex];v[currentIndex] = temp;}else{break;}currentIndex = parentIndex;}}T remove() throw(runtime_error){if(v.size() == 0){throw runtime_error("Heap is empty");}T removedElement = v[0];v[0] = v[v.size()-1];v.pop_back();int currentIndex = 0;while(currentIndex < v.size()){int leftChildIndex = 2 * currentIndex + 1;int rightChildIndex = 2 * currentIndex + 2;if(leftChildIndex >= v.size())break;int minIndex = leftChildIndex;if(rightChildIndex < v.size()){if(v[minIndex] > v[rightChildIndex]){minIndex = rightChildIndex;}}if(v[currentIndex] > v[minIndex]){T temp = v[currentIndex];v[currentIndex] = v[minIndex];v[minIndex] = temp;currentIndex = minIndex;}else{break;}}return removedElement;}int getSize(){return v.size();}private:vector<T> v;};//利用堆实现的优先队列(每次弹出最小的元素)template <typename T>class PriorityQueue{public:PriorityQueue(){}void enqueue(T element){heap.add(element);}T dequeue() throw (runtime_error){heap.remove();}int getSize(){return heap.getSize();}private:Heap<T> heap;};//堆排序的实现void heapAdjust(int a[], int s, int m){ //向下调整,建立大根堆int temp = a[s];int i, j;for(j=s*2; j<=m; j*=2){if(j<m && a[j]<a[j+1]){j++;}if(temp >= a[j]){break;}a[s] = a[j];s = j;}a[s] = temp;}void HeapSort(int a[], int n){int i;for(i=(n-1)/2; i>=0; i--){heapAdjust(a, i, n-1);}for(i=n-1; i>0; i--){int temp = a[i];a[i] = a[0];a[0] = temp;heapAdjust(a, 0, i-1);}}int main(){int a[7] = {12, 34, 11, 13, 29, 48, 35};HeapSort(a, 7);for(int i=0; i<7; i++){printf("%d ", a[i]);}return 0;}
- 编程珠玑(2)第十四章学习笔记之“堆”
- 【编程珠玑】第十四章 堆(排序,优先级队列)
- 编程珠玑第十四章—堆
- 编程珠玑(2)第七章 学习笔记之粗略估算
- 编程珠玑(2)第二章学习笔记
- 编程珠玑(2)第五章 学习笔记
- 编程珠玑(2)第八章学习笔记
- 编程珠玑(2)第九章学习笔记
- 编程珠玑(2)第十章学习笔记
- 编程珠玑(2)第十一章学习笔记
- 编程珠玑(2)第十二章学习笔记 取样问题
- 编程珠玑(2)第十三章学习笔记
- 编程珠玑(2)第十五章学习笔记
- 编程珠玑(2)第六章笔记
- 编程珠玑学习笔记
- 编程珠玑学习笔记
- 编程珠玑第12章(取样问题)学习笔记
- 编程珠玑(2)第一章学习之位图排序
- 2013金山西山居创意游戏程序挑战赛——初赛(1) A 魔法串
- 特效收藏
- 在eclipse中运行工程时 出现<ConnectionProperties> <PropertyCategory name="Connection/Authentication">的解决方法
- Windows 下 Apache HTTP Server 安装、配置以及与 Tomcat 的整合(附图)
- 工业相机介绍
- 编程珠玑(2)第十四章学习笔记之“堆”
- 对象的赋值和复制(转)
- 单板机选型指南
- 颜色特征的提取
- upcoj 2174 二维树状数组
- Clone使用方法详解
- Cocos2d-iphone 开发之(1) cocos2d环境安装图文教程
- 轻松一刻
- awk-数组-待续