赞
踩
在上一篇文章中,我用数组直接存放堆中的元素,导致每次调用有关函数都要传入一个表示堆的大小的值,操作很不方便,今天我用结构体重新实现了堆和堆排序,并在最大堆的基础上实现了最大优先队列,最大优先队列的一个应用就是在共享计算机系统的作业调度中,最优先队列记录将要执行的各个作业以及他们之间的相对优先级。
说明一下,虽然堆排序在实际应用中的性能一般会低于快速排序。两者的时间复杂度均为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>
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。