树的后序遍历
后序遍历按照“左孩子-右孩子-根结点”的顺序进行访问。
1.递归实现
void postOrder(BinTree* root)
{
if(root!=NULL)
{
inOrder(root->lchild);
inOrder(root->rchild);
cout<<root->data;
}
}
2.非递归实现
typedef struct node1
{
BinTree *btnode;
bool isFirst;
}BTNode;
对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
void postOrder(BinTree* root)
{
stack<BTNode*> s;
BinTree* p=root;
BinTree* temp;
while(p!=NULL || !s.emtpy())
{
while(p!=NULL)
{
BTNode *btn=(BTNode*)malloc(sizeof(BTNode));
btn->btnode=p;
btn->isFirst=true;
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
temp=s.top();
s.pop();
if(temp->isFirst==true)
{
temp->isFirst=false;
s.push(temp);
p=temp->btnnode->rchilde;
}
else
{
cout<<temp->btnode->data;
p=NULL:
}
}
}
}