| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2023 人关注过本帖
标题:先根遍历二叉树的非递归算法(大虾们看看对不对)~~~
只看楼主 加入收藏
wsj3000
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:78
专家分:161
注 册:2009-8-4
结帖率:66.67%
收藏
 问题点数:0 回复次数:4 
先根遍历二叉树的非递归算法(大虾们看看对不对)~~~
学数据结构,先根遍历二叉树树,书上给了递归算法,太简洁了;考虑到系统的堆栈内存比较小,大的树用递归可能会报错,所以写了个非递归的算法。(其实就是手动实现操作系统的堆栈功能,但是内存手动非配所以不会因为堆栈太大报错了),花了一个下午写的,大虾们看看对不对呀~~~~


程序代码:
//Preorder.c
typedef struct tNode{
    char data;
    struct tNode * lch;
    struct tNode * rch;
}TreeNode;
/*
void Preorder(TreeNode * p)
{
    if(p!=NULL)
    {
        printf("%c",p->data);
        Preorder(p->lch);
        Preorder(p->rch);
    }
}
*/
//上面是递归算法,太简洁了~~~
================================================================================
//下面是非递归算法,基本思想是用堆栈模拟递归的调用过程(操作系统对递归的调用也是堆栈实现的)
typedef struct sNode{  //堆栈的结构定义
    TreeNode * data;  //指向树节点的指针,堆栈为空时值为NULL
    //指示此树节点是否访问过(或者没有)左右孩子,0:没有,1:左孩子,2,右孩子;堆栈为空值为0
    int status; 
}StackNode;
void Preorder(TreeNode * p) 
{
    InitStack(s); //初始化堆栈S
    TreeNode * cp=p; //cp是指向当前树节点的指针

    while(cp!=NULL)
    {
        if(Get(s).status==0)  //第一次进入此树节点,未访问左右子树
        {
          Insert(cp,0);  //压入堆栈,两个参数分别传值给StackNode结构元素:data,status
          printf("%c",cp->data);
        Get(s).status=1; 
        if(cp->lch!=NULL)
        {
            cp=cp->lch;  //切换当前节点到左孩子
              continue;
        }
        else;
      }
      else;
      if(Get(s).status<=1)  //未访问过左右子树,或者只访问过左子树
      {
        Get(s).status=2;
          if(cp->rch!=NULL)
        {
            cp=cp->rch;  //切换当前节点到右孩子
              continue;
        }
        else;
      }
      else;
        if((Get(s).status==2) //已经访问左右子树,返回父节点;Get(s)返回当前堆栈顶的元素
        {
            Push(s);  //弹出堆栈
            cp=Get(s).data;  //切换当前节点到父节点
        }
        else;
  }    
}



[ 本帖最后由 wsj3000 于 2009-10-26 01:03 编辑 ]
搜索更多相关主题的帖子: 算法 递归 遍历 二叉树 
2009-10-26 00:46
xiefeng122
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:126
专家分:139
注 册:2009-4-1
收藏
得分:0 
感觉楼主对栈的理解还是有问题的,你的栈的定义
typedef struct sNode{  //堆栈的结构定义
    TreeNode * data;  //指向树节点的指针,堆栈为空时值为NULL
    //指示此树节点是否访问过(或者没有)左右孩子,0:没有,1:左孩子,2,右孩子;堆栈为空值为0
    int status;  
}StackNode;
既然是用到栈,那么int status是没有用的,因为栈本身的特性——先进后出已经能解决树节点是否被访问过,
还有,楼主是用的链栈?
其实做这个用顺序栈比较好吧
程序代码:
void unread(bitree T) 
{ 
    bitree tree[50],p; 
    int top,base; 
    top=base=0; 
    tree[top]=p=T; 
    while(top>=0){ 
        while(p){ 
            p=p->lchild; 
            tree[++top]=p; 
        } 
 
        if(!tree[top]){ 
            top--; 
            if(top>=0){ 
                p=tree[top]; 
                if(p->data) 
                    printf("%c",p->data); 
                p=p->rchild; 
                tree[top]=p; 
            } 
        } 
 
    } 
 
}
这是以前写过的一个中序非递归遍历的算法,,用的是顺序栈,也就是数组,希望对楼主有点启发,以上言论如有错误,欢迎指正!

[ 本帖最后由 xiefeng122 于 2009-10-26 19:40 编辑 ]
2009-10-26 19:39
wsj3000
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:78
专家分:161
注 册:2009-8-4
收藏
得分:0 
哈哈,终于验证了。完全正确。而且巧妙利用了二叉树的定义和顺序栈的性质,佩服~~~~
我的算法也是正确的,不过比较臃肿啊~~~~~
谢谢啦~~~~
分析了一下你的程序,加了些说明,也发出来吧:

程序代码:
void unread(bitree T) //T是指向树根节点的指针
{ 
    bitree tree[50],p; //bitree是指向树节点的指针类型,p指向当前节点
    int top,base;  //top是栈顶位置
    top=base=0; 
    tree[top]=p=T;
    while(top>=0) //判断是否遍历过根节点
    { 
        while(p) //遍历左孩子
        {
            p=p->lchild; 
            tree[++top]=p;
        } 
        if(!tree[top])
        {
            top--;  //如果左孩子为空,退回到父节点
            putchar('\n');
            if(top>=0)
            { 
                p=tree[top]; 
                if(p->data)  //遍历(访问)父节点,输出数据
                    printf("%c",p->data); 
                p=p->rchild;   //遍历右节点
                tree[top]=p;
            }else;
        }else;
    } 
}
2009-10-29 23:34
helloweilin
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2009-10-31
收藏
得分:0 
思路:使用队列。
1,根节点进入队列
2,判断队列是否为空,为空则退出;
3,队列不为空,则取出一个节点N并访问,
4,节点N如果不是左右子树节点,则其左右子树进入队列。
5,重复步骤2.
6,结束。

有些问题使用递归解决,思路清晰,代码简洁,就是直接用递归。
2009-11-01 04:39
wsj3000
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:78
专家分:161
注 册:2009-8-4
收藏
得分:0 
恩,不错,递归是很简单;而且完全按照二叉树的递归定义来遍历二叉树,的确清晰易懂;不过实际编程中,考虑到系统堆栈可能会溢出,才使用非递归程序的。
2009-11-05 00:04
快速回复:先根遍历二叉树的非递归算法(大虾们看看对不对)~~~
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.031903 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved