二叉树相关功能的实现

一.本篇博客的主要内容

1.二叉树的前序遍历递归创建

2.拷贝二叉树(赋值运算符重载和拷贝构造函数)

3.二叉树的前序遍历

4.二叉树的中序遍历

5.二叉树的后序遍历

6.二叉树的层序遍历

7.二叉树的所有结点个数

8.二叉树的叶子结点个数

9.求第k层的结点个数

10.求二叉树的高度(深度)

11.在二叉树中查找某个元素,并返回元素结点位置

12.查找某个结点的双亲结点,并返回双亲结点位置

13.查找左右孩子,并返回孩子的结点位置

14.销毁二叉树

给出二叉树形象图:


注意:算法代码的实现是在类中封装起来的。下面给出代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<queue>
using namespace std;

//二叉树的结点
template<class T>
struct BinTreeNode
{
	BinTreeNode<T> *_pLeft;
	BinTreeNode<T>* _pRight;
	T _data;
	BinTreeNode(const T& data)
		:_pLeft(NULL)
		, _pRight(NULL)
		, _data(data){}
};
template<class T>

class Bintree//二叉树的封装
{
	typedef BinTreeNode<T> Node;
	typedef BinTreeNode<T> *_PNode;
public:
	Bintree()
	{
		_pRoot = NULL;
	}
	Bintree(const T *array, size_t size,const T& invalid)//前序遍历创建二叉树
	{
		size_t index = 0;//索引下标
		_CreatBinTree(_pRoot, array, size,index,invalid);
	}
	Bintree(const Bintree<T>& bt)//拷贝构造函数
	{
		_pRoot = _CopyBinTree(bt._pRoot);
	}
	Bintree<T>& operator=(const Bintree<T>& bt)//赋值运算符重载
	{
		if (this != &bt)
		{
			_DestroyBinTree(_pRoot);
			_pRoot = _CopyBinTree(bt._pRoot);
		}
		return *this;
	}
	void _DestroyBinTree(_PNode& pRoot)//销毁二叉树
	{
		if (pRoot)
		{
			_DestroyBinTree(pRoot->_pLeft);
			_DestroyBinTree(pRoot->_pRight);
			delete pRoot;
			pRoot = NULL;
		}
	}
	void PreOrder()//前序遍历
	{
		_PreOrder(_pRoot);
		cout << endl;
	}
	void InOrder()//中序遍历
	{
		_InOrder(_pRoot);
		cout << endl;
	}
	void PostORder()//后续遍历
	{
		_PostORder(_pRoot);
		cout << endl;
	}
	void LevelOrder()//层序遍历
	{
		_LevelOrder(_pRoot);
	}
	size_t Size()//结点个数
	{
		return _Size(_pRoot);
	}
	size_t GetLeafCount()//求叶子结点的个数
	{
		return _GetLeafCount(_pRoot);
	}
	size_t GetkLeveCount(size_t K)//求第K层的结点的个数,自己完成
	{
		return _GetkLeveCount(_pRoot, K);
	}
	size_t Height()//求二叉树的高度
	{
		return _Height(_pRoot);
	}
	_PNode Find(const T& data)//查找某个结点
	{
		return _Find(_pRoot,data);
	}
	_PNode FindParent(_PNode _Node)//查找双亲结点
	{
		return _FindParent(_pRoot,_Node);
	}
	_PNode Findlchild(_PNode _Node)//查找左孩子
	{
		_Findlchild( _Node);
	}
	_PNode FindRchild(_PNode _Node)//查找左孩子
	{
		_FindRchild( _Node);
	}
	~Bintree()//析构函数
	{
		_DestroyBinTree(_pRoot);
	}
private:
	//创建二叉树的算法代码
	void _CreatBinTree(_PNode& pRoot, const T* array, size_t size,size_t& index, const T& invalid)
	{
		//创建跟结点+左子树+右子数
		if (index < size &&'#' != array[index])
		{
			pRoot = new Node(array[index]);
			_CreatBinTree(pRoot->_pLeft, array, size, ++index, invalid);
			_CreatBinTree(pRoot->_pRight, array, size, ++index, invalid);
		}
	}
	_PNode _CopyBinTree(_PNode pRoot)//拷贝树的算法代码
	{
		_PNode pNewRoot = NULL;
		if (pRoot)
		{
			//拷贝根节点
			pNewRoot = new Node(pRoot->_data);
			//拷贝根节点的左子树
			if (pRoot->_pLeft)
			pNewRoot->_pLeft=_CopyBinTree(pRoot->_pLeft);
			//拷贝右子数
			if (pRoot->_pRight)
			pNewRoot->_pRight = _CopyBinTree(pRoot->_pRight);
		}
		return pNewRoot;
	}
	void _PreOrder(_PNode pRoot)//前序遍历算法代码
	{
		if (pRoot)
		{
			cout << pRoot->_data <<"   ";
			_PreOrder(pRoot->_pLeft);
			_PreOrder(pRoot->_pRight);
		}
	}
	void _InOrder(_PNode pRoot)//中序遍历算法代码
	{
		if (pRoot)
		{
			_InOrder(pRoot->_pLeft);
			cout << pRoot->_data << "   ";
			_InOrder(pRoot->_pRight);
		}
	}
	void _PostORder(_PNode pRoot)//后续遍历算法代码
	{
		if (pRoot)
		{
			_PostORder(pRoot->_pLeft);
			_PostORder(pRoot->_pRight);
			cout << pRoot->_data << "   ";
		}
	}
	void _LevelOrder(_PNode pRoot)//层序遍历算法代码
	{
		queue<_PNode> q;
		if (pRoot == NULL)
		{
			return;
		}
		q.push(pRoot);
		while (!q.empty())
		{
			_PNode pCur = q.front();//得到第一个
			cout << pCur->_data << "   ";
			q.pop();
			if (pCur->_pLeft)
			q.push(pCur->_pLeft);

			if (pCur->_pRight)
			q.push(pCur->_pRight);
		}
	}
	size_t _Size(_PNode pRoot)//所以的结点的个数
	{
		if (NULL == pRoot)
			return 0;
		return _Size(pRoot->_pLeft) + _Size(pRoot->_pRight) + 1;
	}
	size_t _GetLeafCount(_PNode  pRoot)//求叶子结点的个数
	{
		if (NULL==pRoot)
			return 0;
		else if (NULL == pRoot->_pLeft&&NULL==pRoot->_pRight)
			return 1;
		else
			return _GetLeafCount(pRoot->_pLeft) + _GetLeafCount(pRoot->_pRight);
	}
	size_t _GetkLeveCount(_PNode pRoot, size_t  K)//求第k层的结点个数
	{
		if(NULL == pRoot || K < 1)
			return 0;
		if (1 == K)
			return 1;
		return _GetkLeveCount(pRoot->_pLeft, K - 1) + _GetkLeveCount(pRoot->_pRight, K - 1);
	}
	size_t _Height(_PNode pRoot)//数的高度
	{
		if (NULL == pRoot)
			return 0;
		else if(NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)
			return 1;
		else
		{
			size_t leftHight = _Height(pRoot->_pLeft);
			size_t RightHight = _Height(pRoot->_pRight);

			return leftHight > RightHight ? leftHight+1 : RightHight+1;
		}
	}
	_PNode _Find(_PNode pRoot,const T& data)//查找指定的元素
	{
		if (NULL == pRoot)
			return NULL;
		if (pRoot->_data == data)
			return pRoot;

		_PNode pRet;
		if (pRet = _Find(pRoot->_pLeft, data))
		      return pRet;
		else
			return _Find(pRoot->_pRight, data);
	}
	_PNode _FindParent(_PNode pRoot,_PNode _Node)//找结点的双亲
	{
		if (NULL == Root || NULL == _Node || pRoot == _Node)
			return NULL;
		if (pRoot->_pLeft == _Node || pRoot->_pRight == _Node)
			return pRoot;
		_PNode Parent;
		if (Parent = _FindParent(pRoot->_pLeft, _Node))
			return Parent;
		return _FindParent(pRoot->_pRight, _Node);
	}
	_PNode _Findlchild(_PNode pRoot)//找左孩子
	{
		return (NULL == pRoot) ? NULL : _Findlchild(pRoot->_pLeft);
	}
	_PNode _FindRchild(_PNode pRoot)//找右孩子
	{
		return (NULL == pRoot) ? NULL : _Findlchild(pRoot->_pRight);
	}
private:
	_PNode _pRoot;
};
void test()//测试函数
{
	char *pStr = "ABD##E##CF###";
	Bintree<char> bt(pStr, strlen(pStr), '#');

	cout << "前序遍历二叉树:";
	bt.PreOrder();
	cout << endl;
	cout << "层序遍历二叉树:";
	bt.LevelOrder();
	cout << endl;
	cout <<"二叉树所有结点个数:"<< bt.Size()<<endl;
	cout <<"二叉树叶子结点的个数:" <<bt.GetLeafCount()<<endl;
	cout << "二叉树的高度:"<<bt.Height()<<endl;
	BinTreeNode<char> *p = bt.Find('B');
	cout <<"查找到了B:"<< p->_data << endl;;
	cout << "第3层的结点个数:" << bt.GetkLeveCount(3) << endl;;
}
int main()
{
	test();
	system("pause");
	return 0;
}
给出部分测试图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值