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

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

说明一下,虽然堆排序在实际应用中的性能一般会低于快速排序。两者的时间复杂度均为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>


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值