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

算法设计之,堆,堆排序,基于最大堆的最大优先队列的实现(C++实现)

2014-08-08 14:45 876 查看
在上一篇文章中,我用数组直接存放堆中的元素,导致每次调用有关函数都要传入一个表示堆的大小的值,操作很不方便,今天我用结构体重新实现了堆和堆排序,并在最大堆的基础上实现了最大优先队列,最大优先队列的一个应用就是在共享计算机系统的作业调度中,最优先队列记录将要执行的各个作业以及他们之间的相对优先级。

说明一下,虽然堆排序在实际应用中的性能一般会低于快速排序。两者的时间复杂度均为O(nlgn),但是基于堆而构建的优先队列的性能却要好很多。有关优先队列的基本操作,其时间复杂度为O(lgn)。

下面是堆,堆排序,和基于堆的优先队列的C++实现

<span style="font-size:24px;">// heap.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "iostream"
#define arrSize 100
using namespace std;
//用数组定义堆的数据结构,
typedef struct
{
intarr[arrSize];
intarrLength;//数组元素的个数,
intheapSize;//表示有多少个堆元素存储在该数组中,
//虽然arr[0..arrLength-1]都存有数据,但只有arr[0..heapSize-1]中存放的是堆的有效元素,
//所以 0<=heapSize<=arrLength
} Heap;

//用于维护最大堆的性质,假定以 leftChild(i)和rightChild(i)为根节点的二叉树都是最大堆,
//但是 arr[i] 可能小于其孩子,这就违背了最大堆的性质。通过该函数可以调整违反最大堆性质的
//节点,从而使其保持堆的性质
void maxHeapify(Heap*,int);
void buildMaxHeap(Heap*);//构建一个最大堆
void heapSort(Heap*);//利用最大堆进行堆排序
int parent(int);//根据给定节点的下标 i ,计算它的父节点的下标。
int leftChild(int);//根据给定节点的下标 i ,计算它的左孩子节点的下标。
int rightChild(int);//根据给定节点的下标 i ,计算它的右孩子节点的下标。
///////////////////////////////////////////////////////////////////////////////////////////
//以下是最大优先队列函数的声明
int heapMaximum(Heap*);//返回堆中的最大元素
int heapExtractMax(Heap*);//去掉并返回堆中的最大元素
void heapIncreaseKey(Heap*,int i,intkey);//将元素 i 的值增加到 key。
void maxHeapInsert(Heap*,int);//在最大堆中插入一个新元素。
//////////////////////////////////////////////////////////////////////////////////////////
//主函数
int _tmain(int argc, _TCHAR* argv[])
{
intarr[]={4,1,3,2,16,9,10,14,8,7};
Heapheap;
Heap*pheap=&heap,* pheap2;
pheap->arrLength=10;
for(inti=0;i<pheap->arrLength;i++)
pheap->arr[i]=arr[i];
cout<<"原来数组的情况:";
for(inti=0;i<pheap->arrLength;i++)
cout<<pheap->arr[i]<<",";
cout<<endl;
//构建堆
buildMaxHeap(pheap);
pheap2=pheap;
//输出构建后的堆
cout<<"构建成堆后的数组值:";
for(inti=0;i<pheap->heapSize;i++)
cout<<pheap->arr[i]<<",";
cout<<endl;
///////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//返回堆中的最大元素
cout<<"返回堆中的最大元素 : "<<heapMaximum(pheap)<<endl;
//去掉并返回堆中的最大元素
cout<<"去掉并返回堆中的最大元素 :"<<heapExtractMax(pheap)<<endl;
cout<<"去掉最大元素后的堆中元素为:";
for(inti=0;i<pheap2->heapSize;i++)
cout<<pheap->arr[i]<<",";
cout<<endl;
cout<<"将元素 i 的值增加到 key,增大后堆的元素为:";
//将元素 i 的值增加到 key。
heapIncreaseKey(pheap,4,20);
for(inti=0;i<pheap->heapSize;i++)
cout<<pheap->arr[i]<<",";
cout<<endl;
//在最大堆中插入一个新元素。
maxHeapInsert(pheap,30);
cout<<"在最大堆中插入一个新元素后,堆中元素分布为 : ";
for(inti=0;i<pheap->heapSize;i++)
cout<<pheap->arr[i]<<",";
cout<<endl;
//测试堆排序
heapSort(pheap);
cout<<"堆排序后的结果 : ";
//输出堆排序后的结果
for(inti=0;i<pheap->arrLength;i++)
cout<<pheap->arr[i]<<",";
cout<<endl;

return0;
}
//主函数结束
//////////////////////////////////////////////////////////////////////////
void maxHeapify(Heap* heap,int i)
{
intl = leftChild(i);
intr = rightChild(i);
intmaxIndex=0;
if(l<=heap->heapSize-1&& heap->arr[l]>=heap->arr[i])
maxIndex=l;
else
maxIndex= i;
if(r<=heap->heapSize-1&&heap->arr[r]>=heap->arr[maxIndex])
maxIndex= r;
if(maxIndex!=i)
{
inttemp;
temp= heap->arr[maxIndex];
heap->arr[maxIndex]= heap->arr[i];
heap->arr[i]= temp;

maxHeapify(heap,maxIndex);
}
}
/////////////////////////////////////////////////////
void buildMaxHeap(Heap* heap)
{
heap->heapSize  = heap->arrLength;
for(inti=heap->arrLength-1/2;i>=0;i--)
maxHeapify(heap,i);
}
//////////////////////////////////////////////////
int parent(int i)
{
if(i%2==0)
i-=1;
returni/2;
}
int leftChild(int i)
{
return2*i+1;
}
int rightChild(int i)
{
return2*(i+1);
}
///////////////////////////////////////////////
void heapSort(Heap* heap)
{
buildMaxHeap(heap);
for(inti=heap->arrLength-1;i>=0;i--)
{
inttemp;
temp=heap->arr[0];
heap->arr[0]=heap->arr[i];
heap->arr[i]=temp;
heap->heapSize -=1;
maxHeapify(heap,0);
}
}
//以下是最大优先队列函数的实现
//返回堆中的最大元素
int heapMaximum(Heap* heap)
{
returnheap->arr[0];
}
int heapExtractMax(Heap* heap)
{
if(heap->heapSize<0)
cout<<"堆是空的"<<endl;
intmax=heap->arr[0];
heap->arr[0]=heap->arr[heap->heapSize-1];
heap->heapSize-=1;
maxHeapify(heap,0);
returnmax;
}
void heapIncreaseKey(Heap* heap,int i,intkey)
{
i--;
if(heap->arr[i]>key)
cout<<"新值比当前值小"<<endl;
heap->arr[i]=key;
while(i>0&&heap->arr[parent(i)]<key)
{
inttemp =heap->arr[i];
heap->arr[i]=heap->arr[parent(i)];
heap->arr[parent(i)]=temp;
i=parent(i);
}
}
void maxHeapInsert(Heap* heap,int key)
{
heap->heapSize+=1;
heap->arr[heap->heapSize-1]=-100;//假设用-100代替负无穷。
heapIncreaseKey(heap,heap->heapSize,key);</span>


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: