【殷人昆数据结构】第五章5.5 最大堆MinHeap代码的调试

最大堆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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值