您的位置:首页 > 编程语言 > C语言/C++

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

#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++ 数据结构