二叉树的定义与基本操作

一、二叉树的定义

把满足以下两个条件的树形结构叫做二叉树

(1)每个节点的度都步大于2;

(2)每个节点的孩子节点次序不能任意颠倒。

所以,一个二叉树的每个节点只能含有0、1或者2个孩子,而且每个孩子有左右之分,位于左边的交左孩子,位于右边的叫右孩子。


二、二叉树的基本操作

#include<iostream>
#include<queue>
#include<stack>
using namespace std;
//孩子表示法
template<class T>
struct BinTreeNode
{

	BinTreeNode<T>* _lChild;//左孩子
	BinTreeNode<T>* _rChild;
	T _data;
	BinTreeNode(const T& data)
		:_lChild(NULL)
		, _rChild(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;
		CreateBinTree(_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;
	}
	~BinTree()
	{
		DestroyBinTree(_pRoot);
	}
	//前序遍历
	void PreOrder()
	{
		cout << "PreOrder: ";
		_PreOrder(_pRoot);
		cout << endl;
	}
	void PreOrder_Nor1()
	{
		cout << "PreOrder_Nor1: ";
		_PreOrder_Nor1(_pRoot);
		cout << endl;
	}
	void PreOrder_Nor2()
	{
		cout << "PreOrder_Nor2: ";
		_PreOrder_Nor2(_pRoot);
		cout << endl;
	}
	//中序遍历
	void MidOrder()
	{
		cout << "MidOrder: ";
		_MidOrder(_pRoot);
		cout << endl;
	}
	void MidOrder_Nor()
	{
		cout << "MidOrder_Nor: ";
		_MidOrder_Nor(_pRoot);
		cout << endl;
	}
	//后序遍历
	void PostOrder()
	{
		cout << "PostOrder: ";
		_PostOrder(_pRoot);
		cout << endl;
	}
	void PostOrder_Nor()
	{
		cout << "PostOrder_Nor: ";
		_PostOrder_Nor(_pRoot);
		cout << endl;
	}
	//层序遍历
	void LevelOrder()
	{
		cout << "LevelOrder: ";
		_LevelOrder(_pRoot);
		cout << endl;
	}
	//节点的个数
	size_t Size()
	{
		return _Size(_pRoot);
	}
	//求叶节点的个数
	size_t LeefSize()
	{
		return _LeefSize(_pRoot);
	}
	//树的高度
	size_t Height()
	{
		return _Height(_pRoot);
	}
	//查找树的某个节点
	pNode Find(const T&data)
	{
		return _Find(_pRoot,data);
	}
	//找节点的双亲
	pNode Parent(pNode node)
	{
		return _Parent(_pRoot,node);
	}
	//找节点的左孩子
	pNode lChild(pNode node)
	{
		return (node==NULL)?NULL:node->_lChild;
	}
	//找节点的右孩子
	pNode rChild(pNode node)
	{
		return (node == NULL) ? NULL : node->_rChild;
	}
	//树的第K层有多少节点
	size_t GetKChild(size_t K)
	{
		return _GetKChild(_pRoot, K);
	}
private:
	void CreateBinTree(pNode& pRoot, const T* array,
		size_t size, size_t& index, const T& invalid)
	{
		if (index < size&&'#' != array[index])
		{
			//创建根节点
			pRoot = new Node(array[index]);
			//创建左子树
			CreateBinTree(pRoot->_lChild, array, size, ++index, invalid);
			//创建右子树
			CreateBinTree(pRoot->_rChild, array, size, ++index, invalid);
		}
	}
	pNode CopyBinTree(pNode pRoot)
	{
		pNode pNewRoot = NULL;
		if (pRoot)
		{
			//拷贝根节点
			pNewRoot = new Node(pRoot->_data);
			//拷贝根节点的左子树
			if (pRoot->_lChild)
				pNewRoot->_lChild = CopyBinTree(pRoot->_lChild);
			//拷贝根节点的右子树
			if (pRoot->_rChild)
				pNewRoot->_rChild = CopyBinTree(pRoot->_rChild);
		}
		return pNewRoot;
	}
	void DestroyBinTree(pNode pRoot)
	{
		if (pRoot)
		{
			DestroyBinTree(pRoot->_lChild);
			DestroyBinTree(pRoot->_rChild);
			delete pRoot;
			pRoot = NULL;
		}
	}
	//前序遍历(根+左子树+右子树)-->递归实现
	void _PreOrder(pNode& pRoot)
	{
		if (pRoot)
		{
			cout << pRoot->_data << " ";
			_PreOrder(pRoot->_lChild);
			_PreOrder(pRoot->_rChild);
		}
	}
	//前序遍历-->非递归实现1
	//将左右子树都压进栈中,先压右栈,再压左栈
	void _PreOrder_Nor1(pNode pRoot)
	{
		if (pRoot == NULL)
		{
			return;
		}
		stack<pNode> s;
		pNode cur = pRoot;
		s.push(cur);
		while (!s.empty())
		{
			cur = s.top();
			cout << cur->_data << " ";
			s.pop();
			if (cur->_rChild&&cur->_rChild->_data != '#')
			{
				s.push(cur->_rChild);
			}
			if (cur->_lChild&&cur->_lChild ->_data!= '#')
			{
				s.push(cur->_lChild);
			}
		}
	}
	//前序遍历-->非递归实现2
	//只将左子树压进栈中
	void _PreOrder_Nor2(pNode pRoot)
	{
		stack<pNode> s;
		s.push(pRoot);
		while (!s.empty())
		{
			pNode cur = s.top();
			s.pop();
			while (cur)
			{
				cout << cur->_data << " ";
				if (cur->_rChild)
					s.push(cur->_rChild);
				cur = cur->_lChild;
			}
		}
	}
	//中序遍历(左子树+根+右子树)--->递归实现
	void _MidOrder(pNode& pRoot)
	{
		if (pRoot)
		{
			_MidOrder(pRoot ->_lChild);
			cout << pRoot->_data << " ";
			_MidOrder(pRoot->_rChild);
		}
	}
	//中序遍历-->非递归实现
	void _MidOrder_Nor(pNode pRoot)
	{
		stack<pNode>s;
		pNode cur = pRoot;
		while (cur||!s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur=cur->_lChild;
			}
			cur = s.top();
			s.pop();
			cout << cur->_data <<" ";
			if (cur->_rChild)
			{
				cur = cur->_rChild;
			}
			else
			{
				cur = NULL;
			}
		}
	}
	//后序遍历(左子树+右子树+根)-->递归实现
	void _PostOrder(pNode& pRoot)
	{
		if (pRoot)
		{
			_PostOrder(pRoot->_lChild);
			_PostOrder(pRoot->_rChild);
			cout << pRoot->_data << " ";
		}
	}
	//后序遍历-->非递归实现
	void _PostOrder_Nor(pNode& pRoot)
	{
		stack<pNode> s;
		pNode cur = pRoot;
		pNode pPre = NULL;
		while (cur || !s.empty())
		{
			while (cur&&cur != pPre)
			{
				s.push(cur);
				cur = cur->_lChild;
			}
			if (s.empty())
				return;
			cur = s.top();
			if (cur->_rChild != NULL&&cur->_rChild != pPre)
			{
				cur = cur->_rChild;
			}
			else
			{
				cout << cur->_data << " ";
				s.pop();
				pPre = cur;
			}
		}
	}
	//层序遍历
	void _LevelOrder(pNode pRoot)
	{
		if (NULL == pRoot)//空树
			return;
		queue<pNode> qu;
		qu.push(pRoot);
		while (!qu.empty())
		{
			pNode pCur = qu.front();
			cout << pCur->_data << " ";
			if (pCur->_lChild)
				qu.push(pCur->_lChild);
			if (pCur->_rChild)
				qu.push(pCur->_rChild);
			qu.pop();
		}
		cout << endl;
	}
	//节点的个数
	size_t _Size(pNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		if (pRoot)
		{
			return _Size(pRoot->_lChild) + _Size(pRoot->_rChild) + 1;
		}
	}
	//叶节点的个数
	size_t _LeefSize(pNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		else if (NULL == pRoot->_lChild && NULL == pRoot->_rChild)
		{
			return 1;
		}
		else
			return _LeefSize(pRoot->_lChild) + _LeefSize(pRoot->_rChild);
	}
	size_t _Height(pNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		else if (NULL == pRoot->_lChild&&NULL == pRoot->_rChild)
			return 1;
		else
			return _Height(pRoot->_lChild) > _Height(pRoot->_rChild) ? 
			_Height(pRoot->_lChild) + 1: _Height(pRoot->_rChild) + 1;
	}
	pNode _Find(pNode pRoot, const T&data)
	{
		if (NULL == pRoot)
			return NULL;
		else if (data == pRoot->_data)
			return pRoot;
		if (pRoot->_lChild)
			 _Find(pRoot->_lChild, data);
		if (pRoot->_rChild)
		     _Find(pRoot->_rChild, data);
	}
	pNode _Parent(pNode pRoot, pNode node)
	{
		if (NULL == pRoot || NULL == node || node == pRoot)
			return NULL;
		//验证根节点是不是双亲
	    if (pRoot->_lChild == node || pRoot->_rChild == node)
			return pRoot;
		if (pRoot->_lChild)
		    _Parent(pRoot->_lChild, node);
		if(pRoot->_rChild)
			_Parent(pRoot->_rChild, node);
     }
	size_t _GetKChild(pNode pRoot, size_t K)
	{
		if (pRoot == NULL || K < 0)
			return 0;
		if (K == 1)
			return 1;
		return _GetKChild(pRoot->_lChild, K - 1) + _GetKChild(pRoot->_rChild, K - 1);
	}																																																																																																																								
private:
	pNode _pRoot;//节点类型的指针
};

void Test()
{
	char* pStr = "ABD###CE##F";
	BinTree<char> bt1(pStr, strlen(pStr), '#');
	BinTree<char> bt2(bt1);
	bt2.PreOrder();
	bt2.PreOrder_Nor1();
    bt2.PreOrder_Nor2();
	bt2.MidOrder();
	bt2.MidOrder_Nor();
	bt2.PostOrder();
	bt2.PostOrder_Nor();
	bt2.LevelOrder();
	cout<<"Size= "<<bt2.Size()<<endl;
	cout << "LeefSize= " << bt2.LeefSize() << endl;
	cout << "Height= " << bt2.Height() << endl;
	cout << "Find= "<<bt2.Find('C')->_data << endl;
	cout << "Parent= " << bt2.Parent(bt2.Find('E'))->_data << endl;
	cout << "lChild= " << bt2.lChild(bt2.Find('C'))->_data << endl;
	cout << "rChild= " << bt2.rChild(bt2.Find('C'))->_data << endl;
	cout << "GetKChild= " << bt2.GetKChild(3) << endl;
}

int main()
{
	Test();
	system("pause");
	return 0;
}
实现结果截图:



  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值