二叉树的非递归算法

目录

1.前序遍历

大致的思路:

前序遍历伪代码:

2.中序遍历

3.后序遍历

总代码:(以前序遍历为例)


二叉树的非递归办法

1.前序遍历

在遍历完整个左子树后如何找到该节点的右子树的根指针

解决办法:在访问完该节点后,将该节点的指针保存在栈中,以便以后能通过他找到该节点的右子树

大致的思路:

首先将root压入堆栈,之后在p不为空的时候
循环去遍历左子树,并且遇到的每一个左子树都输出,在把指针p保存在堆栈中

当左子树为空的时候,弹出栈顶元素,将p指向栈顶元素,然后再去访问
栈顶元素的右子树,并且输出,入栈。之后再去循环遍历左子树,并且将每一个左子树都输出。。。。

当栈为空而且p=NULL时,循环结束

前序遍历伪代码:

void BiTree::preOrder()
{
    Stack s;
    p=root;
    while(!(p==NULL&&s.isempty()))
    {
        while(p!=NULL)
        {
            visit(p->data);
            s.push(p);
            p=p->lchild;
        }
        
        if(!s.isEmpty())//但是如果这里是空的话怎么办
        {
            p=p.pop();
            p=p->rchild;
        }
    }
}

代码:

​
void BiTree::preorder()

{
    if(root == NULL)
        {
        return;
       }

    stack<Element>  s;
    BiNode*  p = root;
    Element  e;

    while(p!=NULL || !s.empty())
        {
        while(p!=NULL)
           {
            cout << p->data;
            e.ptr = p;
            e.flag = 1;
            s.push(e);
            p = p->lchild;
             }


        if(!s.empty())
            {
                e = s.top();
                s.pop();
                p = e.ptr;

                if(e.flag == 1)
                    {
                    e.flag = 2;
                    s.push(e);
                    p = p->rchild;

                    }
                    else if(e.flag==2)
                    {

                        p=NULL;
                    }

             }
       }

   }

​

2.中序遍历

相同的思路

代码:

void  BiTree::inOrder(){
        
//用非递归法中序遍历(临时建立堆栈)
stack<Element> s;
    BiNode *p = root;
    Element e;

    while (p != NULL || !s.empty())
     {
        while (p != NULL) {
            e.ptr = p;
            e.flag = 1;
            s.push(e);
            p = p->lchild;
        }

        if (!s.empty()) {
            e = s.top();
            s.pop();
            p = e.ptr;

            if (e.flag == 1) {
                cout << p->data;
                e.flag = 2;
                s.push(e);
                p = p->rchild;
            }
        else if(e.flag==2)
      p=NULL;

        }
    }



}

3.后序遍历

代码:

void  BiTree::postOrder(){
        
 //用非递归法后序遍历(临时建立堆栈)

    stack<Element> s;
    BiNode *p = root;
    Element e;

    while (p != NULL || !s.empty()) {
        while (p != NULL) {
            e.ptr = p;
            e.flag = 1;
            s.push(e);
            p = p->lchild;
        }

        if (!s.empty()) {
            e = s.top();
            s.pop();
            p = e.ptr;

            if (e.flag == 1) {
                e.flag = 2;
                s.push(e);
                p = p->rchild;
            } else {
                cout << p->data;
                p = NULL; // 防止重复入栈
            }
        }
    }





      
}

总代码:(以前序遍历为例)

/*
非递归遍历二叉树,前序遍历  
*/
#include  <stack>
#include  <iostream>
using  namespace  std;
const  int  STACKSIZE=100;              //定义栈最大值常量
const  int  QUEUESIZE  =  100;
struct  BiNode{
        char  data;
        BiNode  *lchild,  *rchild;
};
typedef  struct  element{
        BiNode  *ptr;
        int  flag;                                      //1表示第1次出栈,2表示第2次出栈
}Element;

class  BiTree  {
private:
    BiNode  *root;                                        //指向根结点的头指针
public:
    BiTree(){                                                      //构造函数,建立一棵二叉树
          root=  NULL;
          root  =  creat(root);
    }                          
    ~BiTree(){
          release(root);
    }                                        
    void  preOrder();                                //前序遍历二叉树
private:
    BiNode  *creat(BiNode  *bt);        //构造函数调用
    void  release(BiNode  *bt);                              //析构函数调用
};

BiNode  *BiTree  ::creat(BiNode  *bt){
          //用前序遍历法创建二叉树
          char  ch;
          cin  >>  ch;//输入结点的数据信息,假设为字符
          if  (ch  ==  '#')            //建立一棵空树
                    bt  =  NULL;
          else  {
                    bt  =  new  BiNode  ;
                    bt->data  =  ch;                //生成一个结点,数据域为ch
                    bt->lchild  =  creat(bt->lchild);              //递归建立左子树
                    bt->rchild  =  creat(bt->rchild);            //递归建立右子树
        }
        return  bt;
}

/**后序释放二叉树节点*/
void  BiTree::release(BiNode  *bt){
        if(bt==NULL)
        {
                return;
        }
        else
        {        
                release(bt->lchild);
                release(bt->rchild);
        }        
}

void  BiTree::preOrder(){
        
{
    if(root == NULL)
        {
        return;
       }

    stack<Element>  s;
    BiNode*  p = root;
    Element  e;

    while(p!=NULL || !s.empty())
        {
        while(p!=NULL)
           {
            cout << p->data;
            e.ptr = p;
            e.flag = 1;
            s.push(e);
            p = p->lchild;
             }


        if(!s.empty())
            {
                e = s.top();
                s.pop();
                p = e.ptr;

                if(e.flag == 1)
                    {
                    e.flag = 2;
                    s.push(e);
                    p = p->rchild;

                    }
                    else if(e.flag==2)
                    {

                        p=NULL;
                    }

             }
       }

   }




}

int  main(){
        BiTree  tree;
        cout  <<  "NoRecursive  PreOrder  :  ";
        tree.preOrder();

        return  0;
}

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值