非递归遍历主要利用栈这个数据结构后进先出的性质
非递归先序遍历
根节点压栈,栈不空就进入循环,根节点出栈,打印数据域,,如果右孩子不空,压右孩子,
如果左孩子不空,压左孩子,一定要先压右孩子,再压左孩子,一直循环,直到栈为空。
void NPreOrder(BNode *ptr)
{
if(ptr == NULL) return;
stack<BNode*> sta;
sta.push(ptr);
while(!sta.empty())
{
BNode *p = sta.top();
sta.pop();
cout<<p->data;
if(p->right != NULL) //右孩子不空,入栈
sta.push(p->right);
if(p->left != NULL) //左孩子不空,入栈
sta.push(p->left);
}
}
非递归中序遍历
void NInOrder(BNode *ptr)
{
if(ptr == NULL) return;
stack<BNode *> sta;
while(!sta.empty() || ptr != NULL)
{
while(ptr != NULL) //遍历左子树
{
sta.push(ptr); //入栈
ptr = ptr->left;
}
ptr = sta.top();
sta.pop();
cout<<ptr->data;
ptr = ptr->right; //ptr指向右子树
}
}
非递归后序遍历
void NLastOrder(BNode *ptr)
{
if(ptr == NULL) return;
stack<BNode*> sta;
BNode *tag = NULL; //标记右子树已经被访问过了
while(!sta.empty() || ptr != NULL)
{
while(ptr != NULL)
{
sta.push(ptr);
ptr = ptr->left;
}
ptr = sta.top(); //先出栈,不删除
if(ptr->right == NULL || ptr->right == tag)
{
cout<<ptr->data;
sta.pop();
tag = ptr;
ptr = NULL; //这句很关键
}
else //右孩子不空且右孩子没有被访问
{
ptr = ptr->right;
}
}
}