为什么需要遍历二叉树?二叉树是非线性数据结构,通过遍历可以将二叉树中的结点访问一次且仅一次,从而得到访问结点的顺序序列。从这个意义上说,遍历操作就是将二叉树中的结点按一定规律线性化的操作,目的在于将非线性化数据结构变成可线性化的访问序列。二叉树的遍历操作是二叉树中最基本的运算。
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T& data = T())
:_data(data)
, _pLeftChild(NULL)
, _pRightChild(NULL)
{}
T _data;
BinaryTreeNode<T>* _pLeftChild;
BinaryTreeNode<T>* _pRightChild;
};
template<class T>
class BinaryTree
{
public:
BinaryTree()
:_pRoot(NULL)
{}
BinaryTree(const T array[], size_t size)
:_pRoot(NULL)
{
size_t index = 0;
_CreatBinaryTree(_pRoot, array, size, index);
}
BinaryTree(BinaryTree<T>& tree)
{
_pRoot = _CopyBinartTree(tree._pRoot);
}
BinaryTree<T>& operator=(BinaryTree<T>& tree)
{
if (this != &tree)
{
this->~BinaryTree();
_pRoot = _CopyBinartTree(tree._pRoot);
}
return *this;
}
void PreOrder()
{
_PreOreder(_pRoot);
}
void InOrder()
{
_InOrder(_pRoot);
}
void PostOrder()
{
_PostOrder(_pRoot);
}
~BinaryTree()
{
_DestoryBinaryTree(_pRoot);
}
private:
void _CreatBinaryTree(BinaryTreeNode<T>*& pRoot, const T array[], size_t size, size_t& index)//构造二叉树
{
if (index < size && '#' != array[index])
{
pRoot = new BinaryTreeNode<T>(array[index]);
_CreatBinaryTree(pRoot->_pLeftChild, array, size, ++index);
_CreatBinaryTree(pRoot->_pRightChild, array, size, ++index);
}
}
BinaryTreeNode<T>*& _CopyBinartTree(BinaryTreeNode<T>*& pRoot)//拷贝二叉树
{
if (pRoot)
{
BinaryTreeNode<T>* pNewRoot = new BinaryTreeNode<T>(pRoot->_data);
pNewRoot->_pLeftChild = _CopyBinartTree(pRoot->_pLeftChild);
pNewRoot->_pRightChild = _CopyBinartTree(pRoot->_pRightChild);
return pNewRoot;
}
else
return _pRoot;
}
void _DestoryBinaryTree(BinaryTreeNode<T>*& pRoot)//销毁二叉树
{
if (pRoot)
{
_DestoryBinaryTree(pRoot->_pLeftChild);
_DestoryBinaryTree(pRoot->_pRightChild);
delete pRoot;
pRoot = NULL;
}
}
void _PreOreder(BinaryTreeNode<T>* proot) //前序遍历
{
if (proot)
{
cout << proot->_data << " ";
_PreOreder(proot->_pLeftChild);
_PreOreder(proot->_pRightChild);
}
}
void _InOrder(BinaryTreeNode<T>* proot) //中序遍历
{
if (proot)
{
_InOrder(proot->_pLeftChild);
cout << proot->_data << " ";
_InOrder(proot->_pRightChild);
}
}
void _PostOrder(BinaryTreeNode<T>* proot) //后续遍历
{
if (proot)
{
_PostOrder(proot->_pLeftChild);
_PostOrder(proot->_pRightChild);
cout << proot->_data << " ";
}
}
void LevelOrder()//层序遍历
{
if (NULL == _pRoot)
return;
queue<BinaryTreeNode<T>*>q;
q.push(_pRoot);
while (!q.empty())
{
BinaryTreeNode<T>*pCur = q.front();
cout << pCur->_data << " ";
if (pCur->_pLeftChild)
q.push(pCur->_pLeftChild);
if (pCur->_pRightChild)
q.push(pCur->_pRightChild);
q.pop();
}
}
public:
void _PreOrder_Nor()//前序遍历--非递归
{
if (NULL == _pRoot)
return;
stack<BinaryTreeNode<T>*> s;
s.push(_pRoot);
while (!s.empty())
{
BinaryTreeNode<T>*pTop = s.top();
cout << pTop->_data <<" ";
s.pop();
if (pTop->_pRightChild)
s.push(pTop->_pRightChild);
if (pTop->_pLeftChild)
s.push(pTop->_pLeftChild);
}
cout << endl;
}
void _InOrder_Nor()//中序遍历--非递归
{
if (NULL == _pRoot)
return;
stack<BinaryTreeNode<T>*> s;
BinaryTreeNode<T>* pCur = _pRoot;
while (pCur != NULL || !s.empty())
{
//找最左边节点
while (pCur)
{
s.push(pCur);
pCur = pCur->_pLeftChild;
}
BinaryTreeNode<T>* pTop = s.top();
cout << pTop->_data << " ";
s.pop();
pCur = pTop->_pRightChild;
}
cout << endl;
}
void _PostOrder_Nor()//后序遍历--非递归
{
if (NULL == _pRoot)
return;
stack<BinaryTreeNode<T>*> s;
BinaryTreeNode<T>* pCur = _pRoot;
BinaryTreeNode<T>* prev = NULL;//最近访问过的节点
while (pCur != NULL || !s.empty())
{
//找最左边节点
while (pCur)
{
s.push(pCur);
pCur = pCur->_pLeftChild;
}
BinaryTreeNode<T>* pTop = s.top();
if (pTop->_pRightChild == NULL || pTop->_pRightChild == prev)
{
cout << pTop->_data << " ";
prev = pTop;
s.pop();
}
else
{
pCur = pTop->_pRightChild;
}
}
}
BinaryTreeNode<T>* GetLeftChild(BinaryTreeNode<T>*pCur)
{
return (NULL == pCur) ? NULL : pCur->_pLeftChild;
}
BinaryTreeNode<T>* GetRightChild(BinaryTreeNode<T>*pCur)
{
return (NULL == pCur) ? NULL : pCur->_pRightChild;
}
BinaryTreeNode<T>* GetParent(BinaryTreeNode<T>*pCur)
{
return _GetParent(_pRoot, pCur);
}
BinaryTreeNode<T>*Find(const T& data)
{
return _Find(_pRoot,data);
}
size_t Height()
{
return _Height(_pRoot);
}
size_t GetLeefNode()
{
return _GetLeefNode(_pRoot);
}
size_t GetKLeveNode(size_t k)//求第k层节点数
{
return _GetKLeveNode(_pRoot,k);
}
bool IsNodeInTree(BinaryTreeNode<T>*pNode)//判断节点在不在树中
{
return _IsNodeInTree(_pRoot,pNode);
}
BinaryTreeNode<T>* GetCommonAncestor(BinaryTreeNode<T>*x1, BinaryTreeNode<T>*x2, stack<BinaryTreeNode<T>*>&s)
{
return _GetCommonAncestor(_pRoot,x1,x2);
}
bool GetNodePath(BinaryTreeNode<T>*pNode, stack<BinaryTreeNode<T>*>&s)
{
return _GetNodePath(_pRoot,pNode,s);
}
BinaryTree<T>ReBuildBinaryTree(T pre[],size_t preSize,T in[],size_t inSize)
{
_ReBuildBinaryTree(_pRoot,pre,preSize,in,0,inSize);
}
private:
BinaryTreeNode<T>* _GetParent(BinaryTreeNode<T>*pRoot,BinaryTreeNode<T>*pCur)//获取该结点的父亲结点
{
if (NULL == pRoot || NULL == pCur)
return NULL;
if (pCur == pRoot)
return NULL;
if (pRoot->_pLeftChild == pCur || pRoot->_pRightChild == pCur)
return pRoot;
BinaryTreeNode<T>* parent;
if (parent = _GetParent(pRoot->_pLeftChild, pCur))
return parent;
return _GetParent(pRoot->_pRightChild, pCur);
}
BinaryTreeNode<T>*_Find(BinaryTreeNode<T>*pRoot,const T&data)//查找值为data的结点
{
if (NULL == pRoot)
return NULL;
if (pRoot->_data == data)
return pRoot;
BinaryTreeNode<T>* ret;
if (ret = _Find(pRoot->_pLeftChild, data))
return ret;
return _Find(pRoot->_pRightChild, data);
}
size_t _Height(BinaryTreeNode<T>*pRoot)//求树的高度
{
if (NULL == pRoot)
return 0;
if (NULL == pRoot->_pLeftChild&&NULL == pRoot->_pRightChild)
return 1;
size_t _leftHeight = _Height(pRoot->_pLeftChild);
size_t _rightHeight = _Height(pRoot->_pRightChild);
return (_leftHeight > _rightHeight) ? (_leftHeight + 1) : (_rightHeight + 1);
}
size_t _GetLeefNode(BinaryTreeNode<T>* pRoot)//求叶子节点数
{
if (pRoot == NULL)
return 0;
if (pRoot->_pLeftChild == NULL && pRoot->_pRightChild == NULL)
return 1;
return _GetLeefNode(pRoot->_pLeftChild) + _GetLeefNode(pRoot->_pRightChild);
}
size_t _GetKLeveNode(BinaryTreeNode<T>*pRoot, size_t k)//第k层的节点数
{
if (NULL == pRoot || k<1 || k>Height())
return 0;
if (1 == k)
return 1;
return _GetKLeveNode(pRoot->_pLeftChild, k - 1) + _GetKLeveNode(pRoot->_pRightChild, k - 1);
}
bool _IsNodeInTree(BinaryTreeNode<T>*pRoot,BinaryTreeNode<T>*pNode)
{
if (NULL == pRoot || NULL == pNode)
{
return false;
}
if (pRoot == pNode)
{
return true;
}
if (_IsNodeInTree(pRoot->_pLeftChild, pNode) || _IsNodeInTree(pRoot->_pRightChild, pNode))
{
return true;
}
return false;
}
BinaryTreeNode<T>* _GetCommonAncestor(BinaryTreeNode<T>*pRoot,BinaryTreeNode<T>*x1, BinaryTreeNode<T>*x2)//获取最近的祖先节点
{
if (NULL == pRoot || x1 == pRoot || x2 == pRoot)
return NULL;
if (!_IsNodeInTree(pRoot, x1) || !_IsNodeInTree(pRoot, x2))
return NULL;
bool x1InLeft = _IsNodeInTree(pRoot->_pLeftChild, x1);
bool x1InRight = _IsNodeInTree(pRoot->_pRightChild, x1);
bool x2InLeft = _IsNodeInTree(pRoot->_pLeftChild, x2);
bool x2InRight = _IsNodeInTree(pRoot->_pRightChild, x2);
if ((x1InLeft && x2InRight) || (x1InRight && x2InLeft))
return pRoot;
if ((x1InLeft && x2InLeft))
return _GetCommonAncestor(pRoot->_pLeftChild,x1,x2);
if ((x1InRight && x2InRight))
return _GetCommonAncestor(pRoot->_pRightChild, x1, x2);
}
bool _GetNodePath(BinaryTreeNode<T>*pRoot,BinaryTreeNode<T>*pNode, stack<BinaryTreeNode<T>*>&s)
{
if (NULL == pRoot)
return false;
if (pRoot == pNode)
return true;
s.push(pRoot);
if (pRoot->_pLeftChild && _GetNodePath(pRoot->_pLeftChild, pNode, s))
return true;
if (pRoot->_pRightChild && _GetNodePath(pRoot->_pRightChild, pNode, s))
return true;
s.pop();
return false;
}
void _ReBuildBinaryTree(BinaryTreeNode<T>*&pRoot, T pre[],size_t& index ,size_t preSize, T in[], size_t left, size_t right)
{
if (left >= right || preSize != (right - left))
return;
//在中序中找index的元素
size_t idx = left;
while (idx < left)
{
if (pre[index] == in[idx])
break;
idx++;
}
if (idx == right)
return ;
pRoot = BinaryTreeNode<T>(pre[index]);
//创建根的左子树
_ReBuildBinaryTree(pRoot->_pLeftChild, pre, ++index, preSize, in, left, idx);
//创建根的右子树
_ReBuildBinaryTree(pRoot->_pRightChild, pre, ++index, preSize, in, idx+1, right);
}
private:
BinaryTreeNode<T>* _pRoot;
};
void Test()
{
char *pTreeInfo = "abd###ce##f";
BinaryTree<char> tree(pTreeInfo, strlen(pTreeInfo));
BinaryTree<char> t1(tree);
BinaryTree<char> t2;
t2 = tree;
BinaryTreeNode<char>* pCur = tree.Find('e');
BinaryTreeNode<char>* parent=tree.GetParent(pCur);
size_t size = tree.GetLeefNode();
//cout<<tree.GetCommonAncestor(tree.Find('b'), tree.Find('d'))->_data << endl;
//cout << size << endl;
//size = tree.GetKLeveNode(2);
//cout << size << endl;
//cout << tree.IsNodeInTree(tree.Find('e')) << endl;
tree._PreOrder_Nor();
//tree.PreOrder(); cout << endl;
//tree.InOrder(); cout << endl;
//tree.PostOrder();
//tree._InOrder_Nor();
//tree._PostOrder_Nor();
}
int main()
{
Test();
system("pause");
return 0;
}