最大堆MinHeap
文章目录
主函数
#include <fstream>
#include "MaxHeap.h"
using namespace std;
int main(){
ifstream fin("data.txt");
assert(fin);
int n;
assert(fin >> n);
int * a = new int[n];
cout << "There are " << n << " nodes in the file.\n";
cout << "The value of each node is:\n";
for(int i = 0; i < n; i++){
fin >> a[i];
cout << "node[" << i << "]: " << a[i] << endl;
}
MaxHeap<int/*,int*/> h(a,n);
cout<<"The MaxHeap is: \n";
h.output();
cout<<"+-----------------------------------------------------+"<<endl;
cout<<"Test bool Insert(const Item& x)"<<endl;
cout<<"Please input a value to insert : ";
int t;
cin>>t;
h.Insert(t);
cout<<"The new Maxheap is : ";
h.output();
cout<<"+-----------------------------------------------------+"<<endl;
cout<<"Test bool RemoveMax(Item& x);"<<endl;
h.RemoveMax(t);
cout<<"The new heap is : ";
h.output();
cout<<"The max removed is : "<<t<<endl;
cout << "Press enter to exit!\n";
cin.ignore(100, '\n');
char ch;
cin.get(ch);
return 0;
}
MinHeap最大堆类定义
const int DefaultSize=50;
template <typename E/*,class K*/>class MaxHeap{
//K为关键码的数据类型,E为记录的结构类型
public:
MaxHeap(int sz = DefaultSize);//构造函数:建立空堆
MaxHeap(E arr[], int n); //构造函数:通过一个数组建堆
~MaxHeap() {
delete []heap;
}
bool Insert(const E &x);
bool RemoveMax(E &x);
bool IsEmpty()const{
return currentSize == 0;
}
bool IsFull()const{
return currentSize == maxHeapSize;
}
void MakeEmpty(){
currentSize = 0;
}
void Swap(int i, int j){
E tmp = heap[i];
heap[i] = heap[j];
heap[j] = tmp;
}
void output(){//自定义函数,顺序输出最大堆元素
for(int i = 0; i<currentSize; i++)
cout<<heap[i]<<" ";
cout<<endl;
}
private:
E *heap; //存放最大堆中元素的数组
int currentSize; //最大堆中当前元素个数
int maxHeapSize; //最大堆最多允许元素个数
void siftDown(int start, int m);//从start到m下滑调整为最大堆
void siftUp(int start); //从start到0上滑调整成为最大堆
};
提问1:什么叫关键码的结构类型?
构造函数
//建立空堆
template <typename E/*,class K*/>MaxHeap<E/*, K*/>::MaxHeap(int sz){
maxHeapSize = (DefaultSize < sz) ? sz : DefaultSize;
heap = new E[maxHeapSize];
assert(heap);
currentSize = 0;
}
//通过一个数组建堆
template <typename E/*,class K*/>MaxHeap<E/*, K*/>::MaxHeap(E arr[], int n){
maxHeapSize = (DefaultSize < n) ? n : DefaultSize;
heap = new E[maxHeapSize];
assert(heap);
for (int i = 0; i < n; i++ ){
heap[i] = arr[i];
}
currentSize = n;
int currentPos = (currentSize-2)/2; //找最初调整位置:最后分支结点
while (currentPos >= 0){ //自底向上逐步扩大形成堆
siftDown(currentPos, currentSize -1); //局部自上向下下滑调整
currentPos--; //再向前换一个分支结点
}
}
siftDown函数——下滑调整法
template <typename E/*,class K*/>void MaxHeap<E/*, K*/>::siftDown(int start, int m){
int i = start, j = 2*i+1;//j是i的左子女位置
E temp = heap[i];
while (j <= m){
//检查是否到最后位置
//让j指向两子女中的小者
if (j < m && heap[j] < heap[j+1]){
j++;
}
if (temp >= heap[j]){
break;
}
else{
heap[i] = heap[j];
i = j;
j = 2*j+1;
}
}
heap[i] = temp; //回放temp中暂存的元素
}
siftUp函数——上滑调整算法
template <typename E/*,class K*/>void MaxHeap<E/*, K*/>::siftUp(int start){
int j = start, i = (j-1)/2;
E temp = heap[j];
while (j > 0){ //沿父结点路径向上直达根
if (heap[i] >= temp){
break;
}
else{
heap[j] = heap[i];
j = i;
i = (i-1)/2;
}
}
heap[j] = temp; //回放temp中暂存的元素
}
Insert函数——将x插入最大堆
template <typename E/*,class K*/>
bool MaxHeap<E/*, K*/>::Insert(const E &x){
if (currentSize == maxHeapSize){ //堆满
cerr << "Heap Full" << endl;
return false;
}
heap[currentSize] = x; //插入
siftUp(currentSize); //向上调整
currentSize++; //堆计数加1
return true;
}
RemoveMax函数
template <typename E/*,class K*/>bool MaxHeap<E/*, K*/>::RemoveMax(E &x){
if (!currentSize){ //堆空,返回false
cout << "Heap empty" << endl;
return false;
}
x = heap[0]; //返回最大元素
heap[0] = heap[currentSize-1]; //最后元素填补到根结点
currentSize--;
siftDown(0, currentSize-1); //自上向下调整为堆
return true;
}
注意:
1、堆的同级大小随意;
2、最后heap[currentSize]处还有数据,但不会被今后但函数操作。
整一个头文件
#ifndef MAXHEAP_H
#define MAXHEAP_H
#include <iostream>
#include <cassert>
using namespace std;
const int DefaultSize=50;
template <typename E/*,class K*/>class MaxHeap{ // KΪ¹Ø¼üÂëµÄÊý¾ÝÀàÐÍ£¬EΪ¼Ç¼µÄ½á¹¹ÀàÐÍ
public:
MaxHeap(int sz = DefaultSize);//¹¹Ô캯Êý£º½¨Á¢¿Õ¶Ñ
MaxHeap(E arr[], int n); //¹¹Ô캯Êý£ºÍ¨¹ýÒ»¸öÊý×齨¶Ñ
~MaxHeap() {
delete []heap;
}
bool Insert(const E &x);
bool RemoveMax(E &x);
bool IsEmpty()const{
return currentSize == 0;
}
bool IsFull()const{
return currentSize == maxHeapSize;
}
void MakeEmpty(){
currentSize = 0;
}
void Swap(int i, int j){
E tmp = heap[i];
heap[i] = heap[j];
heap[j] = tmp;
}
void output(){//×Ô¶¨Ò庯Êý£¬Ë³ÐòÊä³ö×î´ó¶ÑÔªËØ
for(int i = 0; i<currentSize; i++)
cout<<heap[i]<<" ";
cout<<endl;
}
private:
E *heap; //´æ·Å×î´ó¶ÑÖÐÔªËصÄÊý×é
int currentSize; //×î´ó¶ÑÖе±Ç°ÔªËظöÊý
int maxHeapSize; //×î´ó¶Ñ×î¶àÔÊÐíÔªËظöÊý
void siftDown(int start, int m);//´Óstartµ½mÏ»¬µ÷Õû³ÉΪ×î´ó¶Ñ
void siftUp(int start); //´Óstartµ½0ÉÏ»¬µ÷Õû³ÉΪ×î´ó¶Ñ
};
// ¹¹Ô캯Êý£º½¨Á¢¿Õ¶Ñ
template <typename E/*,class K*/>MaxHeap<E/*, K*/>::MaxHeap(int sz){
maxHeapSize = (DefaultSize < sz) ? sz : DefaultSize;
heap = new E[maxHeapSize];
assert(heap);
currentSize = 0;
}
// ¹¹Ô캯Êý£ºÍ¨¹ýÒ»¸öÊý×齨¶Ñ
template <typename E/*,class K*/>MaxHeap<E/*, K*/>::MaxHeap(E arr[], int n){
maxHeapSize = (DefaultSize < n) ? n : DefaultSize;
heap = new E[maxHeapSize];
assert(heap);
for (int i = 0; i < n; i++ ){
heap[i] = arr[i];
}
currentSize = n;
int currentPos = (currentSize-2)/2; //ÕÒ×î³õµ÷ÕûλÖÃ:×îºó·ÖÖ§½áµã
while (currentPos >= 0){ //×Ôµ×ÏòÉÏÖð²½À©´óÐγɶÑ
siftDown(currentPos, currentSize -1); //¾Ö²¿×ÔÉÏÏòÏÂÏ»¬µ÷Õû
currentPos--; //ÔÙÏòÇ°»»Ò»¸ö·ÖÖ§½áµã
}
}
//˽Óк¯Êý£º×î´ó¶ÑµÄÏ»¬µ÷ÕûËã·¨
template <typename E/*,class K*/>void MaxHeap<E/*, K*/>::siftDown(int start, int m){
int i = start, j = 2*i+1;//jÊÇiµÄ×ó×ÓŮλÖÃ
E temp = heap[i];
while (j <= m){//¼ì²éÊÇ·ñµ½×îºóλÖÃ
//ÈÃjÖ¸ÏòÁ½×ÓÅ®ÖеÄСÕß
if (j < m && heap[j] < heap[j+1]){
j++;
}
if (temp >= heap[j]){
break;
}
else{
heap[i] = heap[j];
i = j;
j = 2*j+1;
}
}
heap[i] = temp; //»Ø·ÅtempÖÐÔÝ´æµÄÔªËØ
}
// ˽Óк¯Êý£º×î´ó¶ÑµÄÉÏ»¬µ÷ÕûËã·¨
template <typename E/*,class K*/>void MaxHeap<E/*, K*/>::siftUp(int start){
int j = start, i = (j-1)/2;
E temp = heap[j];
while (j > 0){ //Ñظ¸½áµã·¾¶ÏòÉÏÖ±´ï¸ù
if (heap[i] >= temp){
break;
}
else{
heap[j] = heap[i];
j = i;
i = (i-1)/2;
}
}
heap[j] = temp; //»Ø·ÅtempÖÐÔÝ´æµÄÔªËØ
}
// ¹«¹²º¯Êý: ½«x²åÈëµ½×î´ó¶ÑÖÐ
template <typename E/*,class K*/>bool MaxHeap<E/*, K*/>::Insert(const E &x){
if (currentSize == maxHeapSize){ //¶ÑÂú
cerr << "Heap Full" << endl;
return false;
}
heap[currentSize] = x; //²åÈë
siftUp(currentSize); //ÏòÉϵ÷Õû
currentSize++; //¶Ñ¼ÆÊý¼Ó1
return true;
}
// ¹«¹²º¯Êý£º×î´ó¶ÑµÄɾ³ýËã·¨
template <typename E/*,class K*/>bool MaxHeap<E/*, K*/>::RemoveMax(E &x){
if (!currentSize){ //¶Ñ¿Õ, ·µ»Øfalse
cout << "Heap empty" << endl;
return false;
}
x = heap[0]; // ·µ»Ø×î´óÔªËØ
heap[0] = heap[currentSize-1]; //×îºóÔªËØÌî²¹µ½¸ù½áµã
currentSize--;
siftDown(0, currentSize-1); //×ÔÉÏÏòϵ÷ÕûΪ¶Ñ
return true;
}
#endif