用C语言读取前序建立二叉树

本文详细解析了一次在使用C语言建立二叉树时遇到的问题,通过实例展示了在函数参数中使用指针引用的必要性,并提供了正确实现代码。文章深入探讨了C语言中指针、函数参数与引用之间的关系,帮助读者理解在不同场景下如何正确地使用指针和引用,避免常见错误。
摘要由CSDN通过智能技术生成

     今天做编译原理的由正则表达式生成最小DFA需要用到二叉树结构。于是回顾了一下二叉树的建立。

     今天很惨,我记得以前对于二叉树的建立很熟很熟,并且我还赞叹过利用前序建立树的巧妙。可是今天当我想前序建立树时,却死活建不出来!我只记得了这几步:

                if(ch=='#') 

                  {

                      p=NULL;

                      return ;

                   }

                 p->value=ch;

                creatTree(p->lnode);

                creatTree(p->rnode);

              先介绍一下前序建立二叉树的思想。如图1所示的二叉树

      

  其中除‘#’以外的节点是真实的二叉树,也就是需要我们构造的二叉树。现在将每个叶子节点的空子节点用‘#’节点填充,我们姑且称之为#扩展二叉树。然后写出#扩展二叉树的前序遍历:ab#d##c##,这便是我们程序的输入。程序思想是,遇到‘#’便将p赋NULL,如果不是‘#’,就malloc(sizeof(Treenode)),将值赋予Treenode,然后creatTree(p->lnode);creatTree(rnode);

      以下为生成树代码段(注:有误!!)

     

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      

//定义树节点的结构体 
typedef struct Tnode
{
    struct Tnode *lnode;
    struct Tnode *rnode;
    char value;
}Tnode; 

Tnode* root=NULL;
char ch;

//创建二叉树 
void creatTree(Tnode* p)   
{
    scanf("%c",&ch);
    if(ch=='#'){
        p=NULL;
        return ;
    }    
    p=(Tnode*)malloc(sizeof(Tnode));
    p->value=ch;
    creatTree( p->lnode);
    creatTree(p->rnode);
    return ;
}  

//前序遍历二叉树 
void displayTree(Tnode* p)
{
    if(p==NULL) return ; 
    
    displayTree(p->lnode);
    printf("%c",p->value);
    displayTree(p->rnode);
    return ;
}   
//销毁二叉树,回收分配的内存单元   
void destroyTree(Tnode* p)  
{
    if(p==NULL) return;
    destroyTree(p->lnode);
    destroyTree(p->rnode);
    free(p);
}       
int main(){
  
   creatTree(root);
 
   displayTree(root);
   
   destroyTree(root); 
   getch();
   return 1; 
}

     
     
    
    
   
   


    这段代码在算法上没有什么问题,但是却始终遍历不到二叉树!我在调试后,发现是root始终为NULL。我一开始以为是算法问题,但是我模拟了一遍程序运行,发现算法很完善。我在这想了半天。我想到了C语言中函数参数的实参、形参与引用,但是我认为我这是在操作指针,不必加引用。但是结果证明,肯定需要加引用。因为指针变量说到底也是变量,我在函数中操作变量的形参,必然不会引起原参数值的变化。而如果我在函数操作中传入的是这个变量的指针地址,然后对这个指针指向的地址进行操作,便可更改变量的值。下面的代码是正确的:
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       

//定义树节点的结构体 
typedef struct Tnode
{
    struct Tnode *lnode;
    struct Tnode *rnode;
    char value;
}Tnode; 

Tnode* root=NULL;
char ch;

//创建二叉树 
void creatTree(Tnode* &p)   //添加了引用& 
{
    scanf("%c",&ch);
    if(ch=='#'){
        p=NULL;
        return ;
    }    
    p=(Tnode*)malloc(sizeof(Tnode));
    p->value=ch;
    creatTree( p->lnode);
    creatTree(p->rnode);
    return ;
}  

//前序遍历二叉树 
void displayTree(Tnode* p)
{
    if(p==NULL) return ; 
    
    displayTree(p->lnode);
    printf("%c",p->value);
    displayTree(p->rnode);
    return ;
}   
//销毁二叉树,回收分配的内存单元   
void destroyTree(Tnode* p)  
{
    if(p==NULL) return;
    destroyTree(p->lnode);
    destroyTree(p->rnode);
    free(p);
}       
int main(){
  
   creatTree(root);
 
   displayTree(root);
   
   destroyTree(root); 
   getch();
   return 1; 
}

      
      
     
     
    
    

        我在函数形参前加了取址符号&,表示我引用了实参。

        也就是说,我传入的是指向这个变量存储位置的指针,函数可以通过这个指针修改实参的值,所以我对加了引用的形参修改便修改了实参的值。

       重点在于,指针变量也是变量,如果要在函数中想要使对于形参的值修改对应到实参的值修改,必须加引用&。

       关于利用中序、后序建立二叉树的方法,改日再探索。

     

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值