二叉树的建立以及相关操作

这些日子学习二叉树,拖了很长时间来敲二叉树。水平有限,希望各位大牛多多指正。(由于调试比较多,代码风格不太好)

#include <iostream>
#include <queue>
#include <stack>
using namespace std;

template <class T>
class Node{
	public:
		T element;         //数据
		Node <T>* leftChild;        //左孩子结点
		Node <T>* rightChild;       //右孩子结点
	public:
		Node(){
			element = 0;
			leftChild = rightChild = NULL;
		}
		Node(T el,Node<T> *l,Node<T> *r){
			element = el;
			leftChild = l;
			rightChild = r;
		}
		~Node(){}   //默认析构
		void setLeftChild(Node<T>* l);   //设置左孩子结点
		void setRightChild(Node<T>* r);   //设置右孩子结点
		void setValue(const T& val);   // 设置该结点数据
		T getvalue() const;        //返回该结点的数据

		bool isLeaf() const;  //判断该节点是否是叶子结点
		
};


template <class T>
void Node<T>::setValue(const T& val)
{
	element = val;
}


template <class T>
bool Node<T>::isLeaf() const
{
	if (leftChild == NULL && rightChild == NULL)
		return 1;
	else
		return 0;
}


template <class T>
T Node<T>::getvalue() const
{
	return element;
}


template <class T>
void Node<T>::setLeftChild(Node<T>* l)
{
	leftChild = l;
}


template <class T>
void Node<T>::setRightChild(Node<T>* r)
{
	rightChild = r;
}


//二叉树类
template <class T>
class Tree
{
	public:
		Node <T>* root;
	public:
		Tree();//默认构造
	
	~Tree();   //析构
	  	friend Node<T> *makeTree(Node <T>* root);  //建立树 ______///
		bool isEmpty() const;   //判断二叉树是否为空
		Node<T> * getRoot() const; //返回二叉树的根节点
		void del(Node<T>* r);

		void preOrder(Node<T>* root);//前序优先遍历
		void inOrder(Node<T>* root);//中序遍历
		void postOrder(Node<T>* root);//后序优先遍历

		friend void levelOrder();//广度优先遍历

		void preOrder();//前序优先遍历(非递归)
		void inOrder();//中序优先遍历(非递归)
		void postOrder();//后序优先遍历(非递归)

		void NodeCount(Node<T>* root);//求度为特定值的结点个数

		int High(Node<T>* root,int high);//求树的高度

		int MaxValue(Node<T>* root);//求最大的结点

		void Exchang(Node<T>* root);//交换每个结点的左孩子结点和右孩子结点

		void DelLeaf(Node<T>* root);//删除所有叶子结点

		int Width(Node<T>* root);//递归求二叉树的宽度

		bool JudgeComplete(Node<T>* root);//判断该二叉树是否为完全二叉树

};

template <class T>
Node<T> * Tree<T>::getRoot() const
{
	return root;
}

template <class T>
bool Tree<T>::isEmpty() const
{
	if (root == NULL)
		return 1;
	else
		return 0;
}

template <class T>
Tree<T>::Tree()
{
	root = NULL;
}

template <class T>
Tree<T>::~Tree()             //析构函数有问题
{
	Node <T>* temp;
	temp = root;
	if (temp != 0)
	{
		del(temp->leftChild);
		del(temp->rightChild);
	}
}

template <class T>
void Tree<T>::del(Node<T>* r)
{
	delete r;
}


template <class T>
Node <T>* makeTree(Node <T>* root)        // 递归 建立树   //
{
//	if (root)
//		root = new Node(el,left.root,right.root);
//	left.root = right.root = NULL;

	T te;
	cin>>te;
	

	if (te != -1)
	{
		root = new Node<T>;
		root->element = te;
	//	cout<<root->element<<"的左子树"<<endl;
		cout<<"输入"<<root->element<<"的左孩子"<<endl;
		root->leftChild = makeTree(root->leftChild);
	//	cout<<root->element<<"的右子树"<<endl;
		cout<<"输入"<<root->element<<"的右孩子"<<endl;
		root->rightChild = makeTree(root->rightChild);
	
	}

	else
	{
	//	cout<<root<<endl;
		root = NULL;
	}
	return root;     

}

template<class T>
bool Tree<T>::JudgeComplete(Node<T>* root)       //判断是否为完全二叉树
{
	queue<Node<T> *> nodeQueue;
	Node <T>* pointer = root;

	if(pointer)
		nodeQueue.push(pointer);
	while (!nodeQueue.empty())
	{
		pointer = nodeQueue.front();
//		cout<<pointer->element<<" ";
		if (pointer == NULL)
			break;
		nodeQueue.pop();
		nodeQueue.push(pointer->leftChild);
		nodeQueue.push(pointer->rightChild);
	}
	while (!nodeQueue.empty())
	{
		pointer = nodeQueue.front();
		if (pointer != NULL)
			return 0;
		nodeQueue.pop();
	}
	return 1;
}





//统计二叉树的宽度
template<class T>
int Tree<T>::Width(Node<T>* root)
{
	int l = 0;
	int r = 0;
	if (root)
	{
		if (root->leftChild == NULL && root->rightChild == NULL)
			return 1;
		else
		{
			if (root->leftChild != NULL)
				l = Width(root->leftChild);
			if (root->rightChild != NULL)
				r = Width(root->rightChild);
		}
	}

	return l+r;
}







//删除所有叶子结点

Node<int>* temp;
template<class T>

void Tree<T>::DelLeaf(Node<T>* root)
{
	
	if (root)
	{
		if (root->leftChild == NULL && root->rightChild == NULL)
		{
			if (temp->leftChild == root)
			{
				temp->leftChild = NULL;
				delete root;
				root = NULL;
			}
			else if (temp->rightChild == root)
			{
				temp->rightChild = NULL;
				delete root;
				root = NULL;
			}
		}
	
	if (root)	
	{	
		temp = root;
		DelLeaf(root->leftChild);
		DelLeaf(root->rightChild);
	}
	}
}






//交换每个结点的左孩子结点和右孩子结点
template<class T>
void Tree<T>::Exchang(Node<T>* root)
{
	Node<T>* p;  //temp
	if (root)
	{
/*		if (root->leftChild == NULL)
			root->leftChild = root->rightChild;
		else if (root->rightChild == NULL)
			root->rightChild = root->leftChild;*/
//		else
//		{
			p = root->leftChild;
			root->leftChild = root->rightChild;
			root->rightChild = p;
//		}
	Exchang(root->leftChild);
	Exchang(root->rightChild);
	}

}






//求最大值的元素
template<class T>
int Tree<T>::MaxValue(Node<T>* root)
{
	int a;
	if (root)
	{
		if (root->leftChild == NULL && root->rightChild == NULL)
			return root->element;
		else if (root->leftChild == NULL)
		{
			if (root->element >= MaxValue(root->rightChild))
				return root->element;
			else
				return MaxValue(root->rightChild);
		}
		else if (root->rightChild == NULL)
		{
			if (root->element >= MaxValue(root->leftChild))
				return root->element;
			else
				return MaxValue(root->leftChild);
		}
		else
		{
		if (root->element >= MaxValue(root->leftChild))
			a = root->element;
		else           //(root->element < MaxValue(root->leftChild))
			a = MaxValue(root->leftChild);
		if (a >= MaxValue(root->rightChild))
			return a;
		else
			return MaxValue(root->rightChild);
		}
	}
//	if (root->leftChild == NULL && root->rightChild == NULL)
//		return root->element;
}





//计算特定度的结点个数
int count0 = 0;
int count1 = 0;
int count2 = 0;
template<class T>
void Tree<T>::NodeCount(Node<T>* root)
{ 
	if (root)
	{
		NodeCount(root->leftChild);
		if (root->leftChild == NULL && root->rightChild == NULL)
			count0++;
		if ((root->leftChild == NULL && root->rightChild != NULL) || (root->leftChild != NULL && root->rightChild == NULL))
			count1++;
		if (root->leftChild != NULL && root->rightChild != NULL)
			count2++;
		NodeCount(root->rightChild);
	}
}


template<class T>
int Tree<T>::High(Node<T>* root,int high)       //求树的高度
{
	if (root)
	{
		if (root->leftChild == NULL && root->rightChild == NULL)
			high = 0;
		else
		{
			if (High(root->leftChild,high) >= High(root->rightChild,high))
				high += High(root->leftChild,high);
			else
				high += High(root->rightChild,high);
		}

	}
	return high;
}


//广度优先遍历
template <class T>
void levelOrder(Node <T>* root)
{
	queue<Node<T> *> nodeQueue;
	Node <T>* pointer = root;
	
	cout<<"=====广度优先遍历====="<<endl;

	if(pointer)
		nodeQueue.push(pointer);
	while (!nodeQueue.empty())
	{
		pointer = nodeQueue.front();
		cout<<pointer->element<<" ";
		nodeQueue.pop();
		if (pointer->leftChild)
			nodeQueue.push(pointer->leftChild);
		if (pointer->rightChild)
			nodeQueue.push(pointer->rightChild);
	}
}

//前序遍历
template <class T>
void Tree<T>::preOrder(Node<T>* root)
{
	//cout<<"======前序遍历======";
	if (root != NULL)
	{
		cout<<root->element<<"  ";
		preOrder(root->leftChild);
		preOrder(root->rightChild);
	}
}

//中序遍历
template <class T>
void Tree<T>::inOrder(Node<T>* root)
{
	if (root != NULL)
	{
		
		inOrder(root->leftChild);
		cout<<root->element<<"  ";
		inOrder(root->rightChild);
	}
}

//后序遍历
template <class T>
void Tree<T>::postOrder(Node<T>* root)
{
	if (root != NULL)
	{
		postOrder(root->leftChild);
		postOrder(root->rightChild);
		cout<<root->element<<"  ";
	}
}


template <class T>
void Tree<T>::preOrder()     //前序遍历二叉树(非递归形式)
{
	stack<Node<T> *> nodestack;
	Node <T>* pointer = root;   //保存根节点
	
	cout<<"========前序遍历二叉树(非递归)========="<<endl;
	while(!nodestack.empty() || pointer)
	{
		if (pointer){
			cout<<pointer->element<<"  ";
			if (pointer->rightChild != NULL)
				nodestack.push(pointer->rightChild);
			pointer = pointer->leftChild;
		}
			else
			{
				pointer = nodestack.top();
				nodestack.pop();
			}
	}
}

template <class T>
void Tree<T>::inOrder()      //中序遍历二叉树(非递归形式 )
{
	stack<Node<T> *> nodestack;
	Node <T>* pointer = root;//保存根节点

	cout<<"========中序遍历二叉树(非递归)========="<<endl;
	while (!nodestack.empty() || pointer)
	{
		if (pointer){
			nodestack.push(pointer);

			
		//	cout<<pointer->element<<"  ";
		
			pointer = pointer->leftChild;
		
		}
		else
		{
			pointer = nodestack.top();
			cout<<pointer->element<<"  ";
			pointer = pointer->rightChild;
			nodestack.pop();
		}
	}
}

template <class T>
/*void Tree<T>::postOrder()//后序优先遍历(非递归)
{
	stack<Node<T> *> nodestack;
	Node <T>* pointer = root;
	int temp = 0;
	int s = 0;
	while (!nodestack.empty() || pointer)
	{
		if (pointer && s == 0){
			nodestack.push(pointer);
			pointer = pointer->leftChild;
			temp = 0;
			s = 0;
		}
		else if (pointer && s == 1)
		{
			pointer = nodestack.top();
			nodestack.pop();
		}
		else if(temp == 0)
		{
			temp = 1;
			pointer = nodestack.top();
			pointer = pointer->rightChild;
		//	nodestack.pop();
		}
		else 
		{
			cout<<pointer->element<<"  ";
			pointer = nodestack.top();
			nodestack.pop();
			s = 1;
			
		}
	}
}*/

void Tree<T>::postOrder() //后序优先遍历
{
	stack<Node <T>*> nodestack;
	Node <T>* pointer = root;
	Node <T>* pre = root;//保存前一个被访问的结点
	cout<<"========后序遍历二叉树(非递归)========="<<endl;
	while (pointer)
	{
		for (;pointer->leftChild != NULL;pointer = pointer->leftChild)
			nodestack.push(pointer);//将所有左孩子结点压栈

		while (pointer != NULL && (pointer->rightChild == NULL || pointer->rightChild == pre)){
			cout<<pointer->element<<"  ";
			pre = pointer;
			if (nodestack.empty())
				return;
			pointer = nodestack.top();//
			nodestack.pop();
		}

		nodestack.push(pointer);
		pointer = pointer->rightChild;  //转向右子树
	}
}


int main()
{
	Tree<int> t;

	t.root = makeTree(t.root);
/*	
//	cout<<t.getRoot();
	levelOrder(t.root);
	cout<<endl<<"======前序遍历======"<<endl;
	t.preOrder(t.root);
	cout<<endl<<"======中序遍历======"<<endl;
	t.inOrder(t.root);
	cout<<endl<<"======后序遍历======"<<endl;
	t.postOrder(t.root);

	cout<<endl;
	t.preOrder();
	
	cout<<endl;
	t.inOrder();
	
	cout<<endl;
	t.postOrder();
*/
	t.NodeCount(t.root);            //计算度为0,1,2的结点的个数
	cout<<"度为0的结点的个数为:"<<count0<<endl<<"度为1的结点的个数为:"<<count1<<endl<<"度为2的结点的个数为:"<<count2<<endl;

	cout<<"该二叉树的高度为:"<<t.High(t.root,1)<<endl;

	cout<<"该二叉树的最大元素的值为:"<<t.MaxValue(t.root)<<endl;

/*	t.Exchang(t.root);
	cout<<"每个结点的左孩子结点和右孩子结点都已经交换"<<endl;
	t.preOrder();

	t.DelLeaf(t.root);
	cout<<"删除叶子结点后的结果:"<<endl;
	t.preOrder();

	cout<<"该二叉树的宽度为:"<<t.Width(t.root)<<endl;
*/
	if (t.JudgeComplete(t.root))
		cout<<"该二叉树是完全二叉树";
	else
		cout<<"该二叉树不是完全二叉树";
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值