码迷,mamicode.com
首页 > 编程语言 > 详细

C++实现二叉树相关操作

时间:2015-07-28 21:11:12      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:二叉树

测试环境:windows 7 vs2010

主要实现二叉树的初始化递归和非递归遍历,层次遍历,获取叶子节点的个数,获取树的高度以及镜像树,部分代码也参考了互联网上的相关资料。

源程序:

BinaryTreeNode.h

#ifndef _BINARY_NODE
#define _BINARY_NODE

#include<iostream>
using namespace std;
template<class ItemType>
struct BinaryTreeNode
{
	ItemType item;
	BinaryTreeNode<ItemType> *leftPtr;
	BinaryTreeNode<ItemType> *rightPtr;
	friend ostream &operator<<(ostream &out,BinaryTreeNode &btn)
	{
		out<<" "<<btn.item;
		return out;
	}
	friend istream &operator>>(istream &input,BinaryTreeNode &btn)
	{
		input>>btn.item;
		return input;
	}
};

#endif
BinaryTree.h

#ifndef _BINARY_TREE
#define _BINARY_TREE

#include"BinaryTreeNode.h"
template<class ItemType>
class BinaryTree
{
private:
	BinaryTreeNode<ItemType> *rootPtr;
	void creatBinaryTree(BinaryTreeNode<ItemType> **rootPtr);
public:
	BinaryTree(BinaryTreeNode<ItemType> *rootPtr=nullptr);
	~BinaryTree(void);
	void initBinaryTree();
	BinaryTreeNode<ItemType> *getTreeRoot() const;
	void mirrorUseRecursion(BinaryTreeNode<ItemType> *rootPtr);//镜像树
	void preOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const;//递归先序遍历
	void inOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const;//递归中序遍历
	void postOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const;//递归后序遍历
	void preOrderUseStack() const;//非递归先序遍历
	void inOrderUseStack() const;//非递归中序遍历
	void postOrderUseStack() const;//非递归后序遍历
	void LevelOrder()const;//层次遍历
	int getLeafNum(BinaryTreeNode<ItemType> *rootPtr) const;//获取树的叶子节点数
	int getHeight(BinaryTreeNode<ItemType> *rootPtr);//获取树高度
	void clear();//清空树
};

#endif

BinaryTree.cpp
#include "BinaryTree.h"
#define TREE_EOF -1
#include<stack>
#include<deque>
template<class ItemType>
BinaryTree<ItemType>::BinaryTree(BinaryTreeNode<ItemType> *rootPtr=nullptr)
{
	this->rootPtr=rootPtr;
}

template<class ItemType>
BinaryTree<ItemType>::~BinaryTree(void)
{
	this->clear();
}

template<class ItemType>
void BinaryTree<ItemType>::creatBinaryTree(BinaryTreeNode<ItemType> **rootPtr)
{
	ItemType data;
	cin>>data;
	if(data!=TREE_EOF)
	{
		*rootPtr=new BinaryTreeNode<ItemType>;
		(*rootPtr)->item=data;
		cout<<"请输入"<<data<<"左子树:"<<endl;
		creatBinaryTree(&(*rootPtr)->leftPtr);
		cout<<"请输入"<<data<<"右子树:"<<endl;
		creatBinaryTree(&(*rootPtr)->rightPtr);
	}
	else
	{
		*rootPtr=nullptr;
	}

}
template<class ItemType>
void  BinaryTree<ItemType>::initBinaryTree()
{
	cout<<"开始创建二叉树 \n"<<endl;
	creatBinaryTree(&this->rootPtr);
}
template<class ItemType>
void BinaryTree<ItemType>::inOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr)const 
{
	if(rootPtr==nullptr)
	{
		return;
	}
	inOrderUseRecursion(rootPtr->leftPtr);
	cout<<*rootPtr;
	inOrderUseRecursion(rootPtr->rightPtr);
}
template<class ItemType>
void BinaryTree<ItemType>::preOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const
{
	if(rootPtr==nullptr)
	{
		return;
	}
	cout<<*rootPtr;
	preOrderUseRecursion(rootPtr->leftPtr);
	preOrderUseRecursion(rootPtr->rightPtr);
}

template<class ItemType>
void BinaryTree<ItemType>::postOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const
{
	if(rootPtr==nullptr)
	{
		return;
	}
	postOrderUseRecursion(rootPtr->leftPtr);
	postOrderUseRecursion(rootPtr->rightPtr);
	cout<<*rootPtr;
}


template<class ItemType>
void BinaryTree<ItemType>::inOrderUseStack() const //中序遍历
{
	stack<BinaryTreeNode<ItemType>*> tempStack;
	BinaryTreeNode<ItemType> *pTree=rootPtr;
	while(pTree!=nullptr||!tempStack.empty())
	{
		while(pTree!=nullptr)
		{
			tempStack.push(pTree);
			pTree=pTree->leftPtr;
		}
		if(!tempStack.empty())
		{
			pTree=tempStack.top();
			tempStack.pop();
			cout<<*pTree;
			pTree=pTree->rightPtr;//出栈指向右子树
		}

	}
}

template<class ItemType>
BinaryTreeNode<ItemType> * BinaryTree<ItemType>::getTreeRoot() const
{
	return  this->rootPtr;
}
template<class ItemType>
void BinaryTree<ItemType>::preOrderUseStack() const//先序遍历
{
	stack<BinaryTreeNode<ItemType>*> tempStack;
	BinaryTreeNode<ItemType> *pTree=rootPtr;
	while(pTree!=nullptr||!tempStack.empty())
	{
		while(pTree!=nullptr)
		{
			cout<<*pTree;
			tempStack.push(pTree);
			pTree=pTree->leftPtr;
		}
		if(!tempStack.empty())
		{
			pTree=tempStack.top();
			tempStack.pop();
			pTree=pTree->rightPtr;//出栈指向右子树
		}

	}
}

template<class ItemType>
void BinaryTree<ItemType>::postOrderUseStack() const//中序遍历
{
	stack<BinaryTreeNode<ItemType>*> tempStack;
	BinaryTreeNode<ItemType> *pTree=rootPtr;
	BinaryTreeNode<ItemType> *preTree=nullptr;
	while(pTree!=nullptr||!tempStack.empty())
	{
		while(pTree!=nullptr)
		{
			tempStack.push(pTree);
			pTree=pTree->leftPtr;
		}
		pTree=tempStack.top();
		//如果当前节点的右子树为空,或者其右子树已经被访问
		if(pTree->rightPtr==nullptr||pTree->rightPtr==preTree)
		{
			cout<<*pTree;
			preTree=pTree;
			tempStack.pop();
			pTree=nullptr;
		}else
		{
			pTree=pTree->rightPtr;
		}

	}
}

template<class ItemType>
void BinaryTree<ItemType>::clear()
{
	stack<BinaryTreeNode<ItemType>*> tempStack;
	BinaryTreeNode<ItemType> *pTree=rootPtr;
	BinaryTreeNode<ItemType> *preTree=nullptr;
	while(rootPtr!=nullptr||!tempStack.empty())
	{
		while(rootPtr->leftPtr!=nullptr)
		{
			tempStack.push(rootPtr->leftPtr);
		}
		pTree=tempStack.top();
		if(pTree->rightPtr==nullptr&&pTree->rightPtr==preTree)
		{
			tempStack.pop();
			delete pTree;
			preTree=pTree;
			pTree=nullptr;
		}
		else
		{
			pTree=pTree->rightPtr;
		}
	}
	this->rootPtr=nullptr;
}
template<class ItemType>
void BinaryTree<ItemType>::LevelOrder() const
{
	deque<BinaryTreeNode<ItemType>*> tempdq;
	BinaryTreeNode<ItemType> * notePtr=this->rootPtr;
	if( notePtr!=nullptr)
	{
		tempdq.push_back(notePtr);
	}
	while(!tempdq.empty())
	{
		notePtr=tempdq.front();
		cout<<*notePtr;
		if(notePtr->leftPtr!=nullptr)
		{
			tempdq.push_back(notePtr->leftPtr);
		}
		if(notePtr->rightPtr!=nullptr)
		{
			tempdq.push_back(notePtr->rightPtr);
		}
		tempdq.pop_front();
	}
}
template<class ItemType>
int BinaryTree<ItemType>::getHeight(BinaryTreeNode<ItemType> *rootPtr)
{
	if(rootPtr==nullptr)
	{
		return 0;
	}
	int lh=getHeight(rootPtr->leftPtr);
	int rh=getHeight(rootPtr->rightPtr);
	return max(lh,rh)+1;
}
template<class ItemType>
void BinaryTree<ItemType>::mirrorUseRecursion(BinaryTreeNode<ItemType> *rootPtr)
{
	if(rootPtr==nullptr)
	{
		return;
	}
	if(rootPtr->leftPtr==nullptr&&rootPtr->rightPtr==nullptr)
	{
		return;
	}
	BinaryTreeNode<ItemType> *tempPtr=rootPtr->leftPtr;
	rootPtr->leftPtr=rootPtr->rightPtr;
	rootPtr->rightPtr=tempPtr;
	mirrorUseRecursion(rootPtr->leftPtr);
	mirrorUseRecursion(rootPtr->rightPtr);
}
template<class ItemType>
int BinaryTree<ItemType>::getLeafNum(BinaryTreeNode<ItemType> *rootPtr) const
{
	if(rootPtr==nullptr)
	{
		return 0;
	}
	if(rootPtr->leftPtr==nullptr&&rootPtr->rightPtr==nullptr)
	{
		return 1;
	}

	return getLeafNum(rootPtr->leftPtr)+getLeafNum(rootPtr->rightPtr);
}

测试程序:main.cpp

#include"BinaryTree.cpp"
using namespace std;
int main()
{
	BinaryTree<int> btree;
	btree.initBinaryTree();

	cout<<"树高:"<<btree.getHeight(btree.getTreeRoot())<<endl;
	cout<<"树叶子节点数:"<<btree.getLeafNum(btree.getTreeRoot())<<endl;

	cout<<"\n递归先序遍历:";
	btree.preOrderUseRecursion(btree.getTreeRoot());
	cout<<"\n非递归先序遍历:";
	btree.preOrderUseStack();

	cout<<"\n递归中序遍历:";
	btree.inOrderUseRecursion(btree.getTreeRoot());
	cout<<"\n非递归中序遍历:";
	btree.inOrderUseStack();

	cout<<"\n递归后序遍历:";
	btree.postOrderUseRecursion(btree.getTreeRoot());
	cout<<"\n非递后先序遍历:";
	btree.postOrderUseStack();

	cout<<"\n层序遍历:";
	btree.LevelOrder();

	btree.mirrorUseRecursion(btree.getTreeRoot());
	cout<<"\n镜像后层序遍历:";
	btree.LevelOrder();
	system("pause");
	return 0;
}
技术分享

技术分享

版权声明:欢迎转载,如有不足之处,恳请斧正。

C++实现二叉树相关操作

标签:二叉树

原文地址:http://blog.csdn.net/huangshanchun/article/details/47110021

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!