码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树先序中序非递归算法

时间:2014-06-20 10:55:49      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:递归算法   遍历      

一直想要写的 二叉树 中序 先序 后序遍历算法
当年学习DS最虚的就是这个,因为非递归算法复杂,测试数据不好弄,只能一个一个手动插入。感觉明显比图的难,虽然大家都觉得图更难。。。。。

递归的太简单了,就不写了。关键是非递归版本。


先序:


我自己的版本:
void RootPreTraverse(Node* p)
{
	Stack S;
	while(S not empty)
	{
		p=S.top();
		S.pop();
		Show(p);
		if(p->right!=null)
			S.push(p->right);
		if(p->left!=null)
			S.push(p->left);
	}
}




后来发现和层序遍历有点相似,区别就在于 用了栈而不是队列,而且入的顺序换一换,否则到时出栈就错了。
感觉有点微妙,虽然比较容易写出来,但是还是有点悬乎,队列换栈差异这么大!
 
网上版本(感觉不好写) www.cppblog.com/ngaut/archive/2006/01/01/2351.aspx


void BT_PreOrderNoRec(pTreeT root)
{
    stack<treeT *> s;


    while ((NULL != root) || !s.empty())
    {
        if (NULL != root)
        {
            visit(root);
            s.push(root);
            root = root->left;
        }
        else //该版本代码相比于下面比较清sang, 
        {
            root = s.top();
            s.pop();
            root = root->right;
        }
    }
}




下面这个和上面是一个思路 blog.csdn.net/fansongy/article/details/6798278
void preorder_dev(bintree t){  
    seqstack s;  
    s.top = -1;     //因为top在这里表示了数组中的位置,所以空为-1  
    if(!t){  
        printf("the tree is empty\n");  
    }else{  
        while(t || s.stop != -1){  
            while(t){    //只要结点不为空就应该入栈保存,与其左右结点无关      
                  printf("%c ",t->data);  
                push(&s,t);  
                t= t->lchild;  
            }  //令有一个版本http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html,这里加了判断if(S not empty()), 感觉有点画蛇添足。因为此处如果栈为空则说明上面while 一定没执行,t为空,同时S empty()那么上一次外层while已经退出了,遍历结束了。可见,此处栈必不空,上面url楼主加了一个永真判断
            t=pop(&s);  
            t=t->rchild;  
        }  
    }  
}




中序:www.cppblog.com/ngaut/archive/2006/01/01/2351.aspx

void BT_InOrderNoRec(pTreeT root)
{
    stack<treeT *> s;
    while ((NULL != root) || !s.empty())
    {
        if (NULL != root)
        {
            s.push(root);
            root = root->left;
        }
        else
        {
            root = s.top();
            visit(root);
            s.pop();
            root = root->right;
        }
    }
}






//和上面preorder_dev 几乎如出一辙,从一个show 的地方就可以看出本质区别,赞博主
void midorder(bintree t){  
    seqstack s;  
    s.top = -1;  
    if(!t){  
        printf("the tree is empty!\n");  
    }else{  
        while(t ||s.top != -1){  
            while(t){  
                push(&s,t);  
                t= t->lchild;  
            }  
            t=pop(&s);  
            printf("%c ",t->data);  
            t=t->rchild;  
        }  
    }  
}






后序由于有点复杂,先搁置,集中力量打击主要部分。


从逻辑上看,两人其实是一样的,如果t不空,执行if,到while 因此次数if 等价于里面执行while,如果t空,则执行else,与另一个代码一致


另外某博客写的
blog.csdn.net/shunrei/article/details/5680579#reply

递归转非递归的模式其实不大general。。所以这个还得暂时没有通用方法。。。

<pre name="code" class="cpp">将初始状态s0进栈
  while (栈不为空)
  {
  退栈,将栈顶元素赋给s;
  if (s是要找的结果) 返回;
  else {
  寻找到s的相关状态s1;
  将s1进栈
  }
  }

后序
//用一个标志位记录是否 左右孩子是否已经被压过栈,如果压过栈了,如果没压栈,会先压站,然后再把该节点压站,因为后面

还要访问(后序),此外还需要把标志位


void PostOrder(TNode* root)
{
    Stack S;
    if( root != NULL )
    {
        S.push(root);
    }
    while ( !S.empty() )
    {
        TNode* node = S.pop(); 
        if ( node->bPushed )
        {   // 如果标识位为true,则表示其左右子树都已经入栈,那么现在就需要访问该节点了
            Visit(node);        
        }
        else
        {   // 左右子树尚未入栈,则依次将 右节点,左节点,根节点 入栈
            if ( node->right != NULL )
            {
                node->right->bPushed = false; // 左右子树均设置为false
                S.push(node->right);
            }
            if ( node->left != NULL )
            {
                node->left->bPushed = false;
                S.push(node->left);
            }
            node->bPushed = true;            // 根节点标志位为true
            S.push(node);
        }
    }
}






http://www.cnblogs.com/baiyanhuang/archive/2011/02/12/1947435.html 

这篇还没看完,mark









二叉树先序中序非递归算法,布布扣,bubuko.com

二叉树先序中序非递归算法

标签:递归算法   遍历      

原文地址:http://blog.csdn.net/richardzrc/article/details/28488477

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!