堆排序是一个不错的原地排序算法.但是一个实现较好的快速排序会优于堆排序。
但是堆数据结构有一个非常重要的用处,就是作为高效的优先级队列.
与堆一样优先级队列也有两种:最大优先级队列和最小优先级队列.
优先级队列是一种用来维护由一组元素构成的集合S的数据结构.
这一组元素的每一个都有一个关键字Key.一个最大优先级队列支持以下操作:
(i) INSERT(S,x) : 把元素x插入到集合S.
(ii) MAXMUM(S) : 返回S中具有最大关键字的元素.
(iii) EXTRACT-MAX(S) : 去掉并返回S中具有最大关键字的元素.
(iv) INCREASE-KEY(S,x,k) : 将x元素的关键字增加到k,k不能小于x之前的关键字.
(i) 分时计算机上的作业调度. (最大优先级队列).
(ii) 基于事件的驱动模拟器.(最小优先级队列).
(i) 类的定义
#ifndef __HEAP_H__ #define __HEAP_H__ class Heap { protected: int* m_data; int m_heapSize; int m_memSize; public: Heap(); Heap(int heapSize); ~Heap(); void ReAlloc(int size=0); }; #endif
#include <stdlib.h> #include <stdio.h> #include <time.h> #include "heap.h" class Heapsort : public Heap { public: Heapsort(int heapSize); ~Heapsort(); void Build_Max_Heap(); void Create(int size); void Max_Heapify(int nodeIndex,int currentHeapSize); void Sort(); bool Verify(); }; #endif
#ifndef __PRIORITYQUEUE_H__ #define __PRIORITYQUEUE_H__ #include "Heapsort.h" class PriorityQueue : public Heapsort { public: PriorityQueue(int heapSize); ~PriorityQueue(); void Insert(int key); int Maxmum(); int Extract_Max(); void Increase_key(int nodeIndex,int newKey); }; #endif
(ii)类的实现
#include "heap.h" #include <stdio.h> #include <malloc.h> Heap::Heap(int heapSize) { m_data = (int*)malloc(sizeof(int) * heapSize); m_heapSize = heapSize; m_memSize = heapSize; } Heap::Heap() { m_data = NULL; m_heapSize = 0; } Heap::~Heap() { if(m_data) { free(m_data); } } void Heap::ReAlloc(int size) { if(m_data) { free(m_data); if(size==0) { m_memSize *= 2; } else { m_memSize = size; } m_data = (int*)malloc(sizeof(int) * m_memSize); } }
#include <stdio.h> #include <malloc.h> #include "PriorityQueue.h" #define INF -0x7fffffff PriorityQueue::PriorityQueue(int heapSize) : Heapsort(heapSize) { } PriorityQueue::~PriorityQueue() { } int PriorityQueue::Maxmum() { return m_data[0]; } int PriorityQueue::Extract_Max() { int maxKey; if(m_heapSize < 1) { printf("heap underflow \n"); return -1; } maxKey = m_data[0]; m_data[0] = m_data[m_heapSize-1]; m_heapSize--; Max_Heapify(0,m_heapSize); return maxKey; } void PriorityQueue::Insert(int key) { m_heapSize++; if(m_heapSize>m_memSize) { ReAlloc(); } m_data[m_heapSize-1] = INF; Increase_key(m_heapSize-1,key); } void PriorityQueue::Increase_key(int nodeIndex,int newKey) { if(newKey<m_data[nodeIndex]) { printf("error : new key is smaller than current key \n"); return; } m_data[nodeIndex] = newKey; int tmpSwap; while(nodeIndex>0 && m_data[(nodeIndex-1)>>1] < m_data[nodeIndex]) { tmpSwap = m_data[nodeIndex]; m_data[nodeIndex] = m_data[(nodeIndex-1)>>1]; m_data[(nodeIndex-1)>>1] = tmpSwap; nodeIndex = (nodeIndex-1)>>1; } }