二叉树 常见操作

本文介绍了一种通用的二叉树数据结构,并详细解释了前序、中序、后序及层次遍历的递归与非递归实现方法。此外,还提供了树的高度计算与布局显示等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

template<class _T>
struct _TNode
{
_T data;
_TNode* pLeft;
_TNode* pRight;
_TNode* pParent;
_TNode()
{
pLeft = pRight = pParent = NULL;
}
};

template<typename _T>
class CBinaryTree
{
public:
CBinaryTree()
{
m_pRoot = NULL;
}
~CBinaryTree()
{
Clear();
}
void CreateTree(const _T& t);
void PreOrder() const;
void InOrder() const;
void PostOrder() const;
void LevelOrder() const;

void Layout() const;
void Layout2() const;

int Height() const;
private:
void CreateTree(_TNode<_T>** ppNode,const _T& t);

CBinaryTree(const CBinaryTree& tree);
CBinaryTree& operator = (const CBinaryTree& tree);

void Clear();
void Clear(_TNode<_T>* pNode);

int Height(const _TNode<_T>* pNode) const;

void inline Visit(const _TNode<_T>* PNode) const;

// 递归
void PreOrder(const _TNode<_T>* pNode) const;
void InOrder(const _TNode<_T>* pNode) const;
void PostOrder(const _TNode<_T>* pNode) const;

//非递归
void PreOrderNoRecursion(const _TNode<_T>* pNode) const;
void InOrderNoRecursion(const _TNode<_T>* pNode) const;
void PostOrderNoRecursion(const _TNode<_T>* pNode) const;
void LevelOrderNoRecursion(const _TNode<_T>* pNode) const;

_TNode<_T>* m_pRoot;
};

template<typename _T>
void CBinaryTree<_T>::Visit(const _TNode<_T>* pNode) const
{
if (pNode != NULL)
{
cout << pNode->data << endl;
}
}

template<typename _T>
void CBinaryTree<_T>::Clear(_TNode<_T>* pNode)
{
if (pNode != NULL)
{
_TNode<_T>* pLeft = pNode->pLeft;
_TNode<_T>* pRight = pNode->pRight;

delete pNode;
Clear(pLeft);
Clear(pRight);
}
}

template<typename _T>
void CBinaryTree<_T>::Clear()
{
stack<_TNode<_T>*,vector<_TNode<_T>*>> TStack;

if (m_pRoot != NULL)
TStack.push(m_pRoot);

_TNode<_T>* pCur = TStack.top();
while (!TStack.empty())
{
TStack.pop();
if (pCur != NULL)
{
TStack.push(pCur->pRight);
TStack.push(pCur->pLeft);

delete pCur;
pCur = NULL;
}
if (!TStack.empty())
{
pCur = TStack.top();
}
}
}

template<typename _T>
void CBinaryTree<_T>::CreateTree(const _T& t)
{
return CreateTree(&m_pRoot,t);
}

template<typename _T>
void CBinaryTree<_T>::CreateTree(_TNode<_T>** ppNode,const _T& t)
{
if (ppNode == NULL)
{
cout << "Invalid Parameter" << endl;
}

if (*ppNode == NULL)
{
*ppNode = new _TNode<_T>;
(*ppNode)->data = t;
}
else
{
if ((*ppNode)->data > t)
{
CreateTree(&(*ppNode)->pLeft,t);
}
else
{
CreateTree(&(*ppNode)->pRight,t);
}
}
}

template<typename _T>
void CBinaryTree<_T>::PreOrder() const
{
PreOrderNoRecursion(m_pRoot);
return PreOrder(m_pRoot);
}

template<typename _T>
void CBinaryTree<_T>::PreOrder(const _TNode<_T>* pNode) const
{
if (pNode == NULL)
return;

Visit(pNode);
PreOrder(pNode->pLeft);
PreOrder(pNode->pRight);
}

template<typename _T>
void CBinaryTree<_T>::PreOrderNoRecursion(const _TNode<_T>* pNode) const
{
stack<const _TNode<_T>*> TStack;

#if 0
if (pNode != NULL)
{
const _TNode<_T>* pCur = pNode;
while (pCur != NULL)
{
Visit(pCur);
if (pCur->pRight != NULL)
{
TStack.push(pCur->pRight);
}

if (pCur->pLeft != NULL)
{
TStack.push(pCur->pLeft);
}

if (!TStack.empty())
{
pCur = TStack.top();
TStack.pop();
}
else
{
pCur = NULL;
}
}
}
#else
const _TNode<_T>* pCur = pNode;
while (!TStack.empty() || (pCur != NULL))
{
while (pCur != NULL)
{
Visit(pCur);
TStack.push(pCur);
pCur = pCur->pLeft;
}
if (!TStack.empty())
{
pCur = TStack.top();
TStack.pop();
pCur = pCur->pRight;
}
}
#endif
}

template<typename _T>
void CBinaryTree<_T>::InOrder() const
{
InOrderNoRecursion(m_pRoot);
return InOrder(m_pRoot);
}

template<typename _T>
void CBinaryTree<_T>::InOrder(const _TNode<_T>* pNode) const
{
if (pNode == NULL)
return;
InOrder(pNode->pLeft);
Visit(pNode);
InOrder(pNode->pRight);
}

template<typename _T>
void CBinaryTree<_T>::InOrderNoRecursion(const _TNode<_T>* pNode) const
{
const _TNode<_T>* pCur = NULL;
stack<const _TNode<_T>*> TStack;

pCur = pNode;
while (!TStack.empty() || (pCur != NULL))
{
while (pCur != NULL)
{
TStack.push(pCur);
pCur = pCur->pLeft;
}

if (!TStack.empty())
{
pCur = TStack.top();
TStack.pop();
Visit(pCur);
pCur = pCur->pRight;
}
}
}

template<typename _T>
void CBinaryTree<_T>::PostOrder() const
{
PostOrderNoRecursion(m_pRoot);
return PostOrder(m_pRoot);
}

template<typename _T>
void CBinaryTree<_T>::PostOrder(const _TNode<_T>* pNode) const
{
if (pNode == NULL)
return;

PostOrder(pNode->pLeft);
PostOrder(pNode->pRight);
Visit(pNode);
}

template<typename _T>
void CBinaryTree<_T>::PostOrderNoRecursion(const _TNode<_T>* pNode) const
{
const _TNode<_T>* pCur = pNode;
const _TNode<_T>* pPre = NULL;
stack<const _TNode<_T>*> TStack;

while (!TStack.empty() || (pCur != NULL))
{
if (pCur != NULL)
{
TStack.push(pCur);
pCur = pCur->pLeft;
}
else
{
pCur = TStack.top();
if ((pCur->pRight != NULL) && (pPre != pCur->pRight))
{
pCur = pCur->pRight;
}
else
{
pPre = pCur;
Visit(pCur);
TStack.pop();
pCur = NULL;
}
}
}
}

template<typename _T>
void CBinaryTree<_T>::LevelOrder() const
{
return LevelOrderNoRecursion(m_pRoot);
}

template<typename _T>
void CBinaryTree<_T>::LevelOrderNoRecursion(const _TNode<_T>* pNode) const
{
queue<const _TNode<_T>*> TQueue;
const _TNode<_T>* pCur = pNode;

while (pCur != NULL)
{
Visit(pCur);
if (pCur->pLeft != NULL)
{
TQueue.push(pCur->pLeft);
}
if (pCur->pRight != NULL)
{
TQueue.push(pCur->pRight);
}

if (!TQueue.empty())
{
pCur = TQueue.front();
TQueue.pop();
}
else
{
pCur = NULL;
}
}
}

template<typename _T>
void CBinaryTree<_T>::Layout() const
{
stack<pair<const _TNode<_T>*,int>> TStack2;
stack<const _TNode<_T>*> TStack;
const _TNode<_T>* pCur = m_pRoot;
int index = 0;

while ( pCur != NULL || !TStack.empty())
{
while (pCur != NULL)
{
TStack.push(pCur);
TStack2.push(make_pair(pCur,index));
pCur = pCur->pLeft;
index++;
}
if (!TStack.empty())
{
pCur = TStack.top();

pair<const _TNode<_T>*,int> node = TStack2.top();

for (int i = 0; i < node.second; ++i)
{
cout << '/t' ;
}
cout << node.first->data << endl;

TStack.pop();
TStack2.pop();
pCur = pCur->pRight;
if (pCur == NULL)
index--;
}
}
}

template<typename _T>
void CBinaryTree<_T>::Layout2() const
{
queue<const _TNode<_T>*> TQueue;
queue<pair<const _TNode<_T>*,int>> TQueue2;
const _TNode<_T>* pCur = m_pRoot;
int index = 0;

while( pCur != NULL)
{
for (int i = 0; i < 12 - index; ++i)
cout << '/t';
cout << pCur->data << endl;

TQueue.push(pCur->pLeft);
TQueue.push(pCur->pRight);
++index;
pCur = TQueue.front();
TQueue.pop();
}
}

template<typename _T>
int CBinaryTree<_T>::Height() const
{
return Height(m_pRoot);
}

template<typename _T>
int CBinaryTree<_T>::Height(const _TNode<_T>* pNode) const
{
if (pNode == NULL)
return 0;

int left = 0;
int right = 0;
left = Height(pNode->pLeft);
right = Height(pNode->pRight);

return left>right?(left+1):(right+1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值