二叉树的前序、中序、后序遍历的递归算法很好实现,这就不写了。
非递归的实现肯定要借助栈来实现
前序非递归的实现:根->左->右
实现1、
借助栈的后进先出的思想,将根节点放入栈中,然后访问栈顶元素(根),然后将右孩子入栈,再将左孩子入栈,由于栈是后进先出,所以先出栈的是左孩子,这样就实现了先访问根,再访问左孩子,最后访问右孩子。
void PreOreder_Nor(Node* pRoot)
{
cout << "前序遍历 "<<endl;
if(pRoot == NULL)
return ;
stack<Node *> s;
s.push(pRoot);
while(!s.empty())
{
Node *pCur = s.top();
//访问根节点
cout << pCur->data << " ";
s.pop();
//先右孩子入栈,再左孩子入栈
if(pCur->right)
s.push(pCur->right)l;
if(pCur->left)
s.push(pCur->left);
}
cout << endl;
}
实现2、
void PreOreder_Nor(Node* pRoot)
{
if(pRoot == NULL)
return;
stack<Node *> s;
Node *p = pRoot;
while(p || !s.empty())
{
//先访问根节点,左子树,需要借助节点进入右子树
while(p)
{
s.push(p);
cout << p->data <<" ";
p = p->left;
}
//p为空,说明左子树访问完
if(!s.empty())
{
p = s.top();
s.pop();
p = p->right;
}
}
}
中序非递归实现:左->根->右
中序非递归,左根右,一样是循环,这次要一直压入左,然后逐个向上遍历根和右。
void InOreder_Nor(Node *pRoot)
{
if(pRoot == NULL)
return ;
stack<Node *> s;
Node *p = pRoot;
while(p || !s.empty())
{
while(p)
{
s.push(p);
p = p->left;
}
//栈顶元素为最左边的节点
//依次访问该节点,并进入右子树
Node *pTop = s.top();
cout << pTop->data<< " ";
s.pop();
p = pTop->right;//访问右子树
}
}
后序非递归:左->右->根
必须判断右孩子访问完或右孩子为空才能访问根节点。
void PostOreder_Nor(Node *pRoot)
{
if(pRoot == NULL)
return ;
stack<Node *> s;
Node *p = pRoot;
Node *pre = NULL;//标记访问过的节点
while(p || !s.empty())
{
while(p)
{
s.push(p);
p = p->left;
}
//找最左边的孩子
Node *pTop = s.top();
//右孩子访问过或右孩子访问过再访问根
if(pTop->right == NULL || pTop->right == pre)
{
cout << pTop->data << " ";
pre = pTop;
s.pop();
}
else//先访问右孩子
{
p = pTop->right;
}
}
}