您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法——二叉堆

2016-01-09 17:40 435 查看

二叉堆(也叫做堆):

本次实现的是最小堆,也就是树的根结点的值是最小的。如果树的根结点的值是最大的,那么该堆是最大堆。
堆是一颗完全二叉树,一颗树高为h的完全二叉树有2^k到2^(k+1)-1个结点,二叉树的高为log(N)

因为二叉树非常有规律,我们用数组来表示二叉树,在数组中我们从数组下标为1处开始存储。

对于数组任意位置i上的元素,其左儿子在2*i上,右儿子在(2*i+1)上,它的父亲则在i/2上。

在堆中,任意一结点的值小于其子结点的值,所以根据最小堆的性质,最小元素总是会在树的根结点处找到。

主要的接口:

插入insert

删除最小元素deleteMin

判断是否为空isEmpty

二叉堆类:

/*************************************************************************
> File Name: BinaryHeap.h
> Author:
> Mail:
> Created Time: 2016年01月09日 星期六 14时28分57秒
************************************************************************/

#ifndef _BINARYHEAP_H
#define _BINARYHEAP_H

#include <vector>
#include <iostream>
using std::vector;
using std::cout;
using std::cin;
using std::endl;

template<class Comparable>
class BinaryHeap{
public:
explicit BinaryHeap(int capacity = 100):currentSize(capacity){}
explicit BinaryHeap(const vector<Comparable> & items);

bool isEmpty() const;
const Comparable & findMin() const;

void insert(const Comparable & x);
void deleteMin();
void deleteMin(Comparable & minItem);
void makeEmpty();
void output();
private:
int currentSize;
vector<Comparable> array;

void buildHeap();
void percolateDown(int hole);
};

template<class Comparable>
BinaryHeap<Comparable>::BinaryHeap(const vector<Comparable> & items):array(items.size() + 10), currentSize(items.size())
{
for (int i = 0; i < items.size(); ++i)
array[i + 1] = items[i];

buildHeap();
}

template<class Comparable>
void BinaryHeap<Comparable>::buildHeap()
{
for (int i = currentSize/2; i > 0; i--){
percolateDown(i);
}
}

template<class Comparable>
void BinaryHeap<Comparable>::output()
{
std::cout << "堆:";
for (int i = 0; i < currentSize; ++i)
cout << array[i+1] << " ";
cout << endl;
}

template<class Comparable>
bool BinaryHeap<Comparable>::isEmpty() const
{
return currentSize == 0;
}
template<class Comparable>
void BinaryHeap<Comparable>::insert(const Comparable & 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;
}
/*删除最小值,也就是删除堆的根*/
template<class Comparable>
void BinaryHeap<Comparable>::deleteMin()
{
if(isEmpty()){
cout << "这是一个空树。" << endl;
return;
}

array[1] = array[currentSize--];
percolateDown(1);
}

/*删除最小值,也就是删除堆的根, 并得到该最小值保存到minItem中*/
template<class Comparable>
void BinaryHeap<Comparable>::deleteMin(Comparable & minItem)
{
if(isEmpty()){
cout << "这是一个空树。" << endl;
return;
}
minItem = array[1];
array[1] = array[currentSize--];
percolateDown(1);
}

template<class Comparable>
void BinaryHeap<Comparable>::percolateDown(int hole)
{
int child;
Comparable tmp = array[hole];
for (; hole * 2 <= currentSize; hole = child){
child = hole * 2;//left child node

if(child != currentSize && array[child+1] < array[child]){//right child node < left child node
child++;
}

if(array[child] < tmp)//less child node < parent node
array[hole] = array[child];//将最小的子结点放在父结点的位置
else
break;
}

array[hole] = tmp;
}

#endif



实例:

/*************************************************************************
> File Name: use_binary_heap.cpp
> Author:
> Mail:
> Created Time: 2016年01月09日 星期六 15时43分24秒
************************************************************************/

#include <iostream>
#include "BinaryHeap.h"
using namespace std;

int main()
{
vector<int> v;
v.push_back(14);
v.push_back(16);
v.push_back(19);
v.push_back(21);
v.push_back(19);
v.push_back(68);
v.push_back(13);
v.push_back(65);
v.push_back(26);
v.push_back(32);
v.push_back(31);

BinaryHeap<int> binHeap(v);
binHeap.output();

vector<int> v2;
v2.push_back(150);
v2.push_back(80);
v2.push_back(40);
v2.push_back(30);
v2.push_back(10);
v2.push_back(70);
v2.push_back(110);
v2.push_back(100);
v2.push_back(20);
v2.push_back(90);
v2.push_back(60);
v2.push_back(50);
v2.push_back(120);
v2.push_back(140);
v2.push_back(130);

BinaryHeap<int> bindHeap2(v2);
bindHeap2.output();
cout << "获得最小元素并删除最小元素:";
int minVal;
bindHeap2.deleteMin(minVal);
cout << minVal << endl;
bindHeap2.output();

return 0;
}






参考:数据结构与算法分析C++描述(6.3节---二叉树)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: