您的位置:首页 > 其它

Heap & HeapSort (using template)

2012-07-20 22:28 267 查看
维基百科的讲解: http://en.wikipedia.org/wiki/Binary_heap

先列出int型的 heap.h 和 heap.cpp,底层用vector实现,包含大顶堆(MaxHeap)和小顶堆(MinHeap)两个类

头文件

#ifndef _HEAP_H_
#define _HEAP_H_

#include <vector>
using namespace std;

class MinHeap {
private:
int currSize;
vector<int> arr;  //从下标1开始存数,arr[0]略过

public:
void insert(int num);
int extractMin();
MinHeap();
void percolateUp(int hole);
void percolateDown(int hole);
int top();
int heapSize();
};

class MaxHeap {
private:
int currSize;
vector<int> arr;  //从下标1开始存数,arr[0]略过

public:
void insert(int num);
int extractMax();
MaxHeap();
void percolateUp(int hole);
void percolateDown(int hole);
int top();
int heapSize();
};
#endif


cpp文件
#include "heap.h"

MinHeap::MinHeap() {
this->currSize = 0;
this->arr.resize(5);
}

void MinHeap::insert(int num) {
if(this->currSize == arr.size() - 2) arr.resize(arr.size() * 2);

int hole = ++currSize;
arr[hole] = num;

percolateUp(hole);
}

void MinHeap::percolateUp(int hole) {
int x = arr[hole];
for( ; hole > 1 && x < arr[hole / 2]; hole /= 2) {
arr[hole] = arr[hole / 2];
}
arr[hole] = x;
}

int MinHeap::extractMin() {
if(this->currSize == 0) return -99999999;  //空堆无法extract

int minItem = this->arr[1];
this->arr[1] = this->arr[currSize--];
percolateDown(1);

return minItem;
}

void MinHeap::percolateDown(int hole) {
int smallChild;
int x = arr[hole];

while( hole * 2 <= this->currSize) {
smallChild = hole * 2;  //left child
if(smallChild + 1 <= currSize && arr[smallChild + 1] < arr[smallChild])
smallChild++; //if right child exist and is smaller, choose right child
if(arr[smallChild] < x)
arr[hole] = arr[smallChild];
else break;
hole = smallChild;
}
arr[hole] = x;
}

int MinHeap::top() {
if(currSize >= 1) return arr[1];
else return -9999999;
}

int MinHeap::heapSize() {
return this->currSize;
}

MaxHeap::MaxHeap() {
this->currSize = 0;
this->arr.resize(5);
}

void MaxHeap::insert(int num) {
if(this->currSize == arr.size() - 2) arr.resize(arr.size() * 2);

int hole = ++currSize;
arr[hole] = num;

percolateUp(hole);
}

void MaxHeap::percolateUp(int hole) {
int x = arr[hole];
for( ; hole > 1 && x > arr[hole / 2]; hole /= 2) {
arr[hole] = arr[hole / 2];
}
arr[hole] = x;
}

int MaxHeap::extractMax() {
if(this->currSize == 0) return -99999999;  //空堆无法extract

int maxItem = this->arr[1];
this->arr[1] = this->arr[currSize--];
percolateDown(1);

return maxItem;
}

void MaxHeap::percolateDown(int hole) {
int bigChild;
int x = arr[hole];

while( hole * 2 <= this->currSize) {
bigChild = hole * 2;  //left child
if(bigChild + 1 <= currSize && arr[bigChild + 1] > arr[bigChild])
bigChild++; //if right child exist and is smaller, choose right child
if(arr[bigChild] > x)
arr[hole] = arr[bigChild];
else break;
hole = bigChild;
}
arr[hole] = x;
}

int MaxHeap::top() {
if(currSize >= 1) return arr[1];
else return -9999999;
}

int MaxHeap::heapSize() {
return this->currSize;
}


二叉堆(Binary Heap)的template代码实现,只实现了小顶堆,主要功能是insert() 和 extractMin():

#include <iostream>
#include <vector>

using namespace std;

template <typename Comparable>
class BinaryHeap {
public:
BinaryHeap();
void insert(const Comparable & x);
Comparable extractMin();
bool isEmpty();
private:
int currSize;
vector<Comparable> arr;
void percolateDown(int hole);
void buildHeap();
};

template<typename Comparable>
BinaryHeap<Comparable>::BinaryHeap() {
currSize = 0;
arr.resize(5); //初始大小
}

/*
* insert item x, allowing duplicates
*/
template<typename Comparable>
void BinaryHeap<Comparable>::insert(const Comparable &x) {
if(currSize == arr.size() - 1)
arr.resize( arr.size() * 2 );

//percolate up
int hole = ++currSize;
for( ; hole > 1 && x < arr[ hole / 2 ]; hole /= 2) {
arr[hole] = arr[hole / 2];
}
arr[hole] = x;
}

/*
* remove the min item and return it
* throw exception is empty
*/
template<typename Comparable>
Comparable BinaryHeap<Comparable>::extractMin() {
//if(isEmpty()) throw UnderflowException();

Comparable minItem = arr[1];
arr[1] = arr[currSize--];
percolateDown(1);
return minItem;
}

/*
* internal method to percolate down in the heap
* hole is the index at which the percolate begins
*/
template<typename Comparable>
void BinaryHeap<Comparable>::percolateDown(int hole) {
int smallerChild;
Comparable tmp = arr[hole];

while( hole * 2 <= currSize ) {
smallerChild = hole * 2;  // smallChild等于左孩子结点
if( smallerChild + 1 <= currSize && arr[smallerChild] < arr[smallerChild + 1])
smallerChild++;  //若有右孩子结点且右孩子结点小,则sC等于右孩子
if( arr[smallerChild] < tmp ){
arr[hole] = arr[smallerChild];
} else break;
hole = smallerChild;
}
arr[hole] = tmp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息