c++实现最大堆建立(链表结构)和堆排序

  建立最大堆并执行堆排序。


#pragma warning (disable: 4715 4018)
#ifndef MAXHEAP_H
#define MAXHEAP_H
#include
#include
#include
#include
class MaxHeapNode//二叉树节点类的定义。
{
	friend void Visit(MaxHeapNode *t);
	friend class MaxHeap;
public://定义构造函数。
	MaxHeapNode(const int &e)
	{
		data = e;
		LeftChild = RightChild = NULL;
	}
private:
	int data;//节点数据。
	MaxHeapNode *LeftChild;//左孩子指针。
	MaxHeapNode *RightChild;//右孩子指针。

};
//最大堆定义
class MaxHeap
{
	friend void Visit(MaxHeapNode *t);
public:
	MaxHeap() { root = NULL; size = 0; };
	int GetRoot();//根??
	void Initialize(int a[],int n);//初始化。
	MaxHeap& Insert(int *a,const int &e,int n);//插入元素
	void Delete();//删除元素。
	void HeapSort();
	void OutPutHeap(){LevelOrder(Visit);};//输出。
private:
	int size;//个数。
	 MaxHeapNode *root;//根节点。
	 MaxHeapNode *tail;//最后一个节点。
	 std::stack Stack;//层序遍历将所有节点储存在栈中,将来用于删除节点和堆排序!
	void LevelOrder(void(*Visit) (MaxHeapNode *u));//层序遍历。

};
int MaxHeap::GetRoot()//得到根节点数据,用于堆排序。
{
	if (root != NULL)
		return (root->data);
	
}
void MaxHeap::LevelOrder(void(*Visit) (MaxHeapNode *u))//层序遍历。
{
	std::queue Q;
	MaxHeapNode *t = root;
	while (t)
	{
		Visit(t);
		if (t->LeftChild) Q.push(t->LeftChild);
		if (t->RightChild) Q.push(t->RightChild);
		if (Q.empty())
			return;
		else
		{
			t = Q.front();
			Q.pop();
		}
	}
}
MaxHeap& MaxHeap::Insert(int *a,const int &e,int n)//定义插入。
{
	//首先判断是不是满二叉树
	//是满二叉树,插入最下一层最左节点。
	//否则插入只有一个孩子的父节点。
	MaxHeapNode *Find = root;
	std::queue Inserting;
	Inserting.push(root);
	int deep = log(size) / log(2) + 1;//计算树的深度。

	int RealSize = pow(2, deep);//计算该深度下满二叉树节点数。

	if (size == RealSize)//是满二叉树。
	{
		//找最下一层的最左节点。
		for (int i = 0; i < deep; ++i)
			Find = Find->LeftChild;
		Find = new MaxHeapNode(e);
		Stack.push(Find);
	}
	else
	{
		while (1)
		{
			Find = Inserting.front();
			Inserting.pop();
			if (Find->LeftChild == NULL || Find->RightChild == NULL)
				break;
			Inserting.push(Find->LeftChild);
			Inserting.push(Find->RightChild);
		}
		if (Find->LeftChild == NULL)
		{
			Find->LeftChild = new MaxHeapNode(e);
			Stack.push(Find->LeftChild);
		}
		else
		{
			Find->RightChild = new MaxHeapNode(e);
			Stack.push(Find->RightChild);
		}
	}
	++size;//多了一个。
	//重构!
	int Mider = 0;
	std::queue QqQ;
	MaxHeapNode *RrR, *LeL, *RiR;
	QqQ.push(root);
	for (int i = 0; i < size; ++i)
	{
		for (int i = 0; i < QqQ.size(); ++i)
			QqQ.pop();
		QqQ.push(root);
		while (!QqQ.empty())
		{
			RrR = QqQ.front();
			if (RrR->LeftChild == NULL || RrR->RightChild == NULL)//不用再处理。
				break;
			QqQ.pop();
			LeL = RrR->LeftChild;
			RiR = RrR->RightChild;

			if (RrR->data < LeL->data)//根元素小于左子树节点,交换。
			{
				Mider = RrR->data;
				RrR->data = LeL->data;
				LeL->data = Mider;
			}
			if (RrR->data < RiR->data)//根节点小于右子树,交换。
			{
				Mider = RrR->data;
				RrR->data = RiR->data;
				RiR->data = Mider;
			}
			QqQ.push(LeL);//左、右子树入队。
			QqQ.push(RiR);
		}
	}
	return *this;
}
void MaxHeap::Initialize(int a[],int n)//定义初始化。
{
	size = n;
	std::queue Q;//用于插入节点。
	MaxHeapNode *l, *r, *rr;
	l = NULL; r = NULL;
	root = new MaxHeapNode(a[0]);
	Q.push(root);
	int index = 1;
	while (true)//构建二叉树!此时不是最大堆。
	{
		if (index >= n)
			break;
		rr = Q.front();

		Q.pop();
		rr->LeftChild = new MaxHeapNode(a[index]);
		l = rr->LeftChild;
		Q.push(l);
		++index;

		if (index >= n)
			break;
		rr->RightChild = new MaxHeapNode(a[index]);
		r = rr->RightChild;
		Q.push(r);
		++index;

		if (index >= n)
			break;
	}
	//重构堆:
	int Mid = 0;
	std::queue QQ;
	MaxHeapNode *RR, *L, *R;
	QQ.push(root);
	for (int i = 0; i < size; ++i)
	{
		for (int i = 0; i < QQ.size(); ++i)
			QQ.pop();
		QQ.push(root);
		while (!QQ.empty())
		{
			RR = QQ.front();
			if (RR->LeftChild == NULL && RR->RightChild == NULL)//不用再处理。
				break;
			QQ.pop();
			L = RR->LeftChild;
			R = RR->RightChild;

			if (L == NULL)
				break;
			else
				if (RR->data < L->data) //根元素小于左子树节点,交换。
				{
					Mid = RR->data;
					RR->data = L->data;
					L->data = Mid;
				}
			if (R == NULL)
				break;
			else
				if (RR->data < R->data)
					//根节点小于右子树,交换。
				{
					Mid = RR->data;
					RR->data = R->data;
					R->data = Mid;
				}
			QQ.push(L);//左、右子树入队。
			QQ.push(R);
		}
	}
	//为私有成员Stack添加元素。
	std::queue Get;
	MaxHeapNode *Gen;
	Get.push(root);
	Stack.push(root);

	int counter = 1;
	while(1)
	{
		if (counter >= size)
			break;
		Gen = Get.front();
		Get.pop();
		Get.push(Gen->LeftChild);
		Stack.push(Gen->LeftChild);
		++counter;
		++
		if (counter >= size)
			break;
		Get.push(Gen->RightChild);
		Stack.push(Gen->RightChild);
		++counter;
		if (counter >= size)
			break;
	}
}
void MaxHeap::Delete()//删除节点,即删除堆的车根,然后重构即可。                                            
{
	
	MaxHeapNode *T;
	tail = Stack.top();
	Stack.pop();
	//经过以下操作,可以找到tail节点的父节点。
	std::queue Use;
	Use.push(root);
	while (1)
	{
		T = Use.front();
		Use.pop();
		if (T->LeftChild == tail || T->RightChild == tail || T->LeftChild == NULL || T->RightChild == NULL)
			break;
		Use.push(T->LeftChild);
		Use.push(T->RightChild);
	}
	//交换最后一个节点元素和根节点的值,并删除这一节点。
	root->data = tail->data;
	if (T->LeftChild == tail)
	{
	
		T->LeftChild = NULL;
	}
	else
	{

		T->RightChild = NULL;
	}
	//重构。
	int Mid = 0;
	std::queue Qq;
	MaxHeapNode *Rr, *Le, *Ri;
	Qq.push(root);
	for (int i = 0; i < size; ++i)
	{
		for (int i = 0; i < Qq.size(); ++i)
			Qq.pop();
		Qq.push(root);
		while (!Qq.empty())
		{
			Rr = Qq.front();
			if (Rr->LeftChild == NULL || Rr->RightChild == NULL)//不用再处理。
				break;
			Qq.pop();
			Le = Rr->LeftChild;
			Ri = Rr->RightChild;

			if (Rr->data < Le->data)//根元素小于左子树节点,交换。
			{
				Mid = Rr->data;
				Rr->data = Le->data;
				Le->data = Mid;
			}
			if (Rr->data < Ri->data)//根节点小于右子树,交换。
			{
				Mid = Rr->data;
				Rr->data = Ri->data;
				Ri->data = Mid;
			}
			Qq.push(Le);//左、右子树入队。
			Qq.push(Ri);
		}
	}
	--size;//大小少了一个。
	//重新初始化私有成员Stack。
	for (int i = 0; i < size; ++i)//删除原有Stack元素。
		Stack.pop();
	std::queue Want;
	MaxHeapNode *RRR;
	Want.push(root);
	Stack.push(root);

	int counter = 1;
	while (1)
	{
		if (counter >= size)
			break;
		RRR = Want.front();
		Want.pop();
		Want.push(RRR->LeftChild);
		Stack.push(RRR->LeftChild);
		++counter;
		if (counter >= size)
			break;
		Want.push(RRR->RightChild);
		Stack.push(RRR->RightChild);
		++counter;
		if (counter >= size)
			break;
	}
}
void MaxHeap::HeapSort()
{	
	int Count = size;
	for (int index = 0; index < Count; ++index)
	{
		std::cout << GetRoot() << " ";
		Delete();
	}
}
void Visit(MaxHeapNode *u)
{
	std::cout << u->data << " ";
}
#endif // !MAXHEAP_H


  当时写的时候对类的编写认识不深,代码中有许多重复。在代码中如果把重构堆的代码实现为私有函数,代码会简介很多。

你可能感兴趣的:(C++,数据结构与算法,C++,算法,数据结构,堆排序)