二叉树的建立及遍历(前、中、后序) xtu-exam 1004

呵呵,忙了一下午加一晚上终于把它一次性A了!

          主要遇到的问题是:1.对二叉树的遍历(前序、中序、后序)不熟悉,包括递归和非递归写法……

                                           2.在非递归建立二叉树过程中一直在犹豫,,,没有分类清楚(当左子树存在时就该一直左左左地建立它,当不存在左子树时,就应该弹出栈,开始考虑最新的右子树,当初始化时-即当指针指向树根时,不论它含左子树或右子树,都会有要么建立左子树,要么有右子树入栈,否则该树仅含一个点--即树根。)

代码:非递归建树,递归遍历。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#define N 1000011
using namespace std;

char s[N];
typedef struct CT{
       char dat;
       struct CT *lchild,*rchild;
}node;

struct STA{
       node *parent;
       int q;
}stack[N];
node *root;
void tran(int k){/*前序遍历,非递归建树*/
     int t,i,top=-1;
     node *pt,*p;
     for(i=1;i<=k;i++)
         if(s[i]!='#'){
            root=(node *)malloc(sizeof(node));
            root->dat=s[i];
            root->lchild=root->rchild=NULL;
            t=i*2;
            pt=root;
            while(((t<=k)&&(s[t]!='#'))||(top>-1)||((t+1<=k)&&(s[t+1]!='#'))){/*左子树存在或者栈未空(右子树存在)*/
                   while(((t<=k)&&(s[t]!='#'))||((t+1<=k)&&(s[t+1]!='#'))){
                         if((t<=k)&&(s[t]!='#')){/*左子树存在,建立*/
                              p=(node *)malloc(sizeof(node));
                              p->dat=s[t];
                              p->lchild=p->rchild=NULL;
                              pt->lchild=p;
                         }
                         if((t+1<=k)&&(s[t+1]!='#')){/*右子树存在,先入栈*/
                            stack[++top].parent=pt;
                            stack[top].q=t/2;
                         }
                         pt=p;
                         t=2*t;
                   }
                   if(top>-1){
                        pt=stack[top].parent;
                        t=stack[top].q*2+1;
                        top--;
                        p=(node *)malloc(sizeof(node));
                        p->dat=s[t];
                        p->lchild=p->rchild=NULL;
                        pt->rchild=p;
                        pt=p;
                        t=2*t;
                   }
            }
            break;
         }
}

void preergodic(node *t){
     if(!t)return;
     printf("%c",t->dat);
     preergodic(t->lchild);
     preergodic(t->rchild);
     free(t);
}
void inergodic(node *t){
     if(!t)return;
     inergodic(t->lchild);
     printf("%c",t->dat);
     inergodic(t->rchild);
     free(t);
}
void postergodic(node *t){
     if(!t)return ;
     postergodic(t->lchild);
     postergodic(t->rchild);
     printf("%c",t->dat);
     free(t);
}
int main(){
    int i,m,n;
    char c;
    scanf("%d",&n);
    while(n--){
          scanf("%d",&m);
          for(i=0;(c=getchar())!='\n';i++)
              s[i]=c;
          tran(i-1);
          switch(m){
          	case 0:
          	    preergodic(root);
          		break;
            case 1:
                inergodic(root);
                break;
            case 2:
                postergodic(root);
                break;
          	default:
          		break;
          }
          printf("\n");
    }
    return 0;
}

/*void create(int i,node **t){
            if(i<k&&s[i]!='#'){

            }
}*/


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值