AreayGK 2014-09-17
1、堆的数据结构使用数组进行存储的
2、堆的数据结构按照完全二叉树的结构进行描述,所以这里关于堆的孩子节点和父节点的关系,构成了堆数据中数据获取的一个入口,下标为i的父节点的两个孩子节点的下标分别是2*i ,2*i+1 不同的起始下标,表示可能有所不同。
3、最大堆可以用于排序,复杂度在O(Nlog(N)),对还是实现优先权队列的数据结构基础
4、下面的代码详细描述了最大堆的一些关键操作
#ifndef MAXHEAP_H
#define MAXHEAP_H
#include <memory.h>
#include <iostream>
using namespace std;
/**
最大堆
*/
class MaxHeap
{
public:
int heapSize;
int * heap;
public:
MaxHeap();
MaxHeap(int heapSize);
virtual ~MaxHeap();
void output_heap();
void init_heap(int a[],int n);
int left(int i);
int right(int i);
void max_heapify(int i);
void max_heapify2(int i);
void build_max_heap();
void heap_sort();
};
#endif // MAXHEAP_H
#include "MaxHeap.h"
MaxHeap::MaxHeap(){
}
MaxHeap::~MaxHeap(){
delete []heap;
}
MaxHeap::MaxHeap(int heapSize):heapSize(heapSize){
heap = new int [heapSize] ;
memset(heap,0,sizeof(int)*heapSize);
}
//左孩子的index
int MaxHeap::left(int i){//下标从0开始的原因
return 2*i+1;
}
//右孩子的index
int MaxHeap::right(int i){
return 2*i +2;
}
/**
输出堆的内容
**/
void MaxHeap::output_heap(){
for(int i=0;i<heapSize;++i){
cout<<heap[i]<<" ";
}
cout<<endl;
}
/**
利用数组初始化堆内容
**/
void MaxHeap::init_heap(int a[], int n){
if(n>heapSize)return ;
else{
heapSize=n;
//memcpy(heap,a,heapSize);
for(int i=0;i<heapSize;++i){
heap[i]=a[i];
}
}
}
/**
调整堆内数组使得其满足堆的性质
调整从i节点开始,这个操作可以保证i节点及其子孙节点都满足
最大堆的特点
*/
void MaxHeap::max_heapify(int i){
int l= left(i);
int r= right(i);
int max_index=0;
//最大孩子的下标
if(l<heapSize&&heap[l]>heap[i]){
max_index=l;
}else {
max_index=i;
}
if(r<heapSize&&heap[r]>heap[max_index]){
max_index=r;
}
if(max_index!=i){
swap(heap[i],heap[max_index]);
max_heapify(max_index);//防止造成子孙节点中出现不满足堆的性质的情况发生
}
}
//堆调整的非递归代码实现
void MaxHeap::max_heapify2(int i){
while(i<heapSize/2){
int l = left (i);
int r = right (i);
int max_index=0;
if(r<heapSize){
max_index = heap[l] > heap[r] ? l : r;
max_index = heap[max_index] > heap[i] ? max_index : i;
}else{
max_index = heap[l] > heap[i] ? l:i;
}
if(max_index!=i){
swap(heap[i],heap[max_index]);
i = max_index;
}
}
}
/**
堆的建立操作
*/
void MaxHeap::build_max_heap(){
for(int i= heapSize/2 +1;i>=0;--i){//从第一个非叶子节点开始调整为最大堆特征
max_heapify(i);
}
}
/**
堆排序,将最后一个元素同堆顶元素交换
每次都能保证取得的是当前最大的元素
max_heapfy(0),调整第一个元素
**/
void MaxHeap::heap_sort(){
build_max_heap();
int t = heapSize;
for(int i=heapSize-1;i>0;--i){
swap(heap[i],heap[0]);
heapSize--;
max_heapify(0);//取出之后对造成的不满足最大堆进行调整
}
heapSize=t;
}