BinaryHeap 的C++实现
2015-11-23 16:55
363 查看
堆是一棵被完全填满的二叉树,底层上的元素从左到右填入,这样的树称为完全二叉树。
一棵高为h的完全二叉树右2^h到2^(h+1) - 1 个结点。完全二叉树的树高为logN。
A
/ \
B C
/ \ / \
D E F G
/ \ /
H I J
_________________________________________________
|_ _| _A_ |_B_|_C_|_D_|_E_|_F_|_G_|_H_|_I_|_J_|_ _|_ _|_ _|
0 1 2 3 4 5 6 7 8 9 10 11 12 13
对于数组中任意位置 i 上的元素,其左儿子在位置2i上,右儿子在(2i + 1)上。它的父亲则在[i / 2] 上。
一个堆数据结构由一个数组和一个表示当前大小的证书组成。
下面的实现代码分为 BinaryHeap.h 和 main.cpp.
模板编程分文件写编译器支持不一,所以一般在一个文件内实现。
BinaryHeap.h
main.cpp
makefile非常非常简单,
不想写mekefile也可以的,编译时输入
输出内容:
以上内容参考《数据结构与算法分析C++描述》。
一棵高为h的完全二叉树右2^h到2^(h+1) - 1 个结点。完全二叉树的树高为logN。
A
/ \
B C
/ \ / \
D E F G
/ \ /
H I J
_________________________________________________
|_ _| _A_ |_B_|_C_|_D_|_E_|_F_|_G_|_H_|_I_|_J_|_ _|_ _|_ _|
0 1 2 3 4 5 6 7 8 9 10 11 12 13
对于数组中任意位置 i 上的元素,其左儿子在位置2i上,右儿子在(2i + 1)上。它的父亲则在[i / 2] 上。
一个堆数据结构由一个数组和一个表示当前大小的证书组成。
下面的实现代码分为 BinaryHeap.h 和 main.cpp.
模板编程分文件写编译器支持不一,所以一般在一个文件内实现。
BinaryHeap.h
#ifndef __BINARY_HEAP_H #define __BINARY_HEAP_H #include <iostream> #include <vector> #include <exception> #include <cstdlib> using std::vector; using std::cout; using std::endl; using namespace std; class UnderflowException : public exception { public : UnderflowException() : exception() { cout << "underflow\n"; exit(0); } }; template <typename T> class BinaryHeap { public: explicit BinaryHeap(int capacity = 100); explicit BinaryHeap(const vector<T> & items); ~BinaryHeap(); bool isEmpty() const; const T & findMin() const; void insert(const T &x); void deleteMin(); void deleteMin(T & minItem); void makeEmpty(); T minimum() const; void print() const; private: int currentSize; // number of elements in heap vector<T> array; // the heap array void buildHeap(); void percolateDown(int hole); }; template <typename T> BinaryHeap<T>::BinaryHeap(int capacity) : array(capacity + 10) { currentSize = 0; } template <typename T> BinaryHeap<T>::BinaryHeap(const vector<T> & item) : array(item.size() + 10), currentSize(item.size()) { for(int i = 0; i < item.size(); ++i) { array[i+1] = item[i]; } buildHeap(); } template <typename T> BinaryHeap<T>::~BinaryHeap() { makeEmpty(); // (array).swap(array); // 匿名对象,来释放空间 array.shrink_to_fit(); // -std=c++11 cout << "array.capacity() " << array.capacity() <<endl; cout << "~BinaryHeap()" << endl; } /** * Establish heap order property from an arbitrary arrangement of items. * Runs in linear time. O(n) */ template <typename T> void BinaryHeap<T>::buildHeap() { for(int i = currentSize / 2; i > 0; --i) percolateDown(i); } template <typename T> void BinaryHeap<T>::makeEmpty() { currentSize = 0; array.clear(); } template <typename T> T BinaryHeap<T>::minimum() const { if(isEmpty()) throw UnderflowException(); return array[1]; } template <typename T> void BinaryHeap<T>::print() const { for(int i = 1 ; i <= currentSize; ++i) cout << array[i] << " "; cout << endl; } template <typename T> inline bool BinaryHeap<T>::isEmpty() const { return currentSize == 0; } /* * Insert item x, allowing duplicates */ template <typename T> void BinaryHeap<T>::insert(const T &x) { if(currentSize == array.size() - 1) { array.resize(array.size() * 2); } int hole = ++currentSize; for( ; hole > 1 && x < array[hole / 2]; hole /= 2) { array[hole] = array[hole / 2]; } array[hole] = x; } /* * Remove the minimum item. * Throws UnderflowException if empty. */ template <typename T> void BinaryHeap<T>::deleteMin() { if(isEmpty()) throw UnderflowException(); array[1] = array[currentSize--]; percolateDown(1); } /* * Remove the minimum item and place it in minItem. * Throws UnderflowException if empty. */ template <typename T> void BinaryHeap<T>::deleteMin(T & minItem) { if(isEmpty) throw UnderflowException(); minItem = array[1]; array[1] = array[currentSize--]; percolateDown(1); } template <typename T> void BinaryHeap<T>::percolateDown(int hole) { int child; T tmp = array[hole]; for( ; (hole << 2) <= currentSize; hole = child) { child = hole << 2; // hole * 2 if(child != currentSize && array[child + 1] < array[child]) child++; if(array[child] < tmp) array[hole] = array[child]; else break; } array[hole] = tmp; } #endif // #ifndef __BINARY_HEAP_H
main.cpp
#include <iostream> #include "BinaryHeap.h" using namespace std; int main(int argc, char **argv) { BinaryHeap<int> bHeap; cout << (bHeap.isEmpty() ? "empty" : "not empty") << endl; //bHeap.deleteMin(); // exception: the Heap is empty bHeap.insert(10); bHeap.insert(2); bHeap.insert(5); bHeap.insert(13); bHeap.insert(1); bHeap.insert(8); cout << "minimum " << bHeap.minimum() << endl; bHeap.print(); bHeap.deleteMin(); bHeap.print(); BinaryHeap<int> bHeap2(bHeap); cout << "bHeap2" << endl << " "; bHeap2.print(); return 0; }
makefile非常非常简单,
# 2015-11-15 # Summer #object = main.o main : g++ -std=c++11 main.cpp -o main #main.o: BinaryHeap.h #g++ -std=c++11 -c main.o main.cpp BinaryHeap.h .PHONY: clean clean: rm -rf $(object) cleanAll: rm -r main $(object)
不想写mekefile也可以的,编译时输入
g++ -std=c++11 main.cpp -o main即可
输出内容:
empty minimum 1 1 2 5 13 10 8 8 2 5 13 10 bHeap2 8 2 5 13 10 array.capacity() 0 ~BinaryHeap() array.capacity() 0 ~BinaryHeap()
以上内容参考《数据结构与算法分析C++描述》。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(七):数据结构详解
- Lua教程(二):C++和Lua相互传递数据示例
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例