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

二叉堆(也叫做堆):

本次实现的是最小堆,也就是树的根结点的值是最小的。如果树的根结点的值是最大的,那么该堆是最大堆。
堆是一颗完全二叉树,一颗树高为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 
#include 
using std::vector;
using std::cout;
using std::cin;
using std::endl;

template
class BinaryHeap{
    public:
        explicit BinaryHeap(int capacity = 100):currentSize(capacity){}
        explicit BinaryHeap(const vector & 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 array;
        
        void buildHeap();
        void percolateDown(int hole);
};


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

    buildHeap();
}

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

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

template
bool BinaryHeap::isEmpty() const
{
    return currentSize == 0;    
}
template
void BinaryHeap::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
void BinaryHeap::deleteMin()
{
    if(isEmpty()){
        cout << "这是一个空树。" << endl;
        return;
    }
    
    array[1] = array[currentSize--];
    percolateDown(1);
}

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

template
void BinaryHeap::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
数据结构与算法——二叉堆_第1张图片

实例:

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

#include 
#include "BinaryHeap.h"
using namespace std;

int main()
{
    vector 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 binHeap(v); 
    binHeap.output();

    vector 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 bindHeap2(v2);
    bindHeap2.output();
    cout << "获得最小元素并删除最小元素:";
    int minVal;
    bindHeap2.deleteMin(minVal);
    cout << minVal << endl;
    bindHeap2.output();

    return 0;
}



数据结构与算法——二叉堆_第2张图片


参考:数据结构与算法分析C++描述(6.3节---二叉树)

你可能感兴趣的:(数据结构与算法)