二叉链表生成二叉树

把例程敲一遍       才对二叉树有了个基本的认识    

完整正确例程:

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include<stdlib.h>  
  3. using namespace std;  
  4. //二叉树出的二叉链表结构定义  
  5. struct bitnode  
  6. {  
  7.     char data;  
  8.     bitnode *lchild,*rchild;  
  9.   
  10. };  
  11.   
  12.   
  13.   
  14. bitnode *t;  
  15. //bitree==*bitnode  
  16. //前序遍历递归  
  17. void preordertraverse(bitnode *t)  
  18. {  
  19.     if(t==NULL)  
  20.         return ;  
  21.     cout<<t->data;  
  22.     preordertraverse(t->lchild);  
  23.     preordertraverse(t->rchild);  
  24. }  
  25.   
  26. //二叉树的中序遍历递归  
  27. void inordertraverse(bitnode *t)  
  28. {  
  29.     if(t==NULL)  
  30.         return ;  
  31.     inordertraverse(t->lchild);  
  32.     cout<<t->data;  
  33.   
  34.     inordertraverse(t->rchild);  
  35. }  
  36. //二叉树后序遍历递归  
  37. void postordertraverse(bitnode *t)  
  38. {  
  39.     if(t==NULL)  
  40.         return ;  
  41.     postordertraverse(t->lchild);  
  42.     postordertraverse(t->rchild);  
  43.     cout<<t->data;  
  44. }  
  45. //按前序输入二叉树中结点的值(一个字符)  
  46. //#表示空树,构造二叉链表表示二叉树t《大话数据结构》  
  47.   
  48. void createbitree(bitnode *(*t))  
  49. {  
  50.     char ch;  
  51.   
  52.     cin>>ch;  
  53.     if(ch=='#')  
  54.         (*t)=NULL;  
  55.     else  
  56.     {  
  57.         (*t)=new bitnode;  
  58.         //if(!t)  
  59.            // exit(0);  
  60.   
  61.         (*t)->data=ch;  
  62.         createbitree(&(*t)->lchild);//构造左子树  
  63.         createbitree(&(*t)->rchild);//构造右子树  
  64.     }  
  65. }  
  66.   
  67.   
  68. int main()  
  69. {  
  70.       
  71.         cout<<"请输入全部结点(空指针用#代替):"<<endl;  
  72.     createbitree(&t);  
  73.     cout<<"\n\n先序遍历"<<endl;  
  74.     inordertraverse(t);  
  75.         cout<<"\n中序遍历"<<endl;  
  76.     preordertraverse(t);  
  77.         cout<<"\n后序遍历"<<endl;  
  78.     postordertraverse(t);  
  79.  cout<<endl;  
  80.     return 0;  
  81. }  

下面是运行结果:


错误的建树函数:

错误原因是:参数有单向传递的特点,修改后的data无法传递到主函数中

[cpp]  view plain  copy
  1. void createbitree(bitnode *t)  
  2. {  
  3.     char ch;  
  4.   
  5.     cin>>ch;  
  6.     if(ch=='#')  
  7.         t=NULL;  
  8.     else  
  9.     {  
  10.         t=new bitnode;  
  11.         //if(!t)  
  12.            // exit(0);  
  13.   
  14.         t->data=ch;  
  15.         createbitree(t->lchild);//构造左子树  
  16.         createbitree(t->rchild);//构造右子树  
  17.     }  
  18. }*/  


修改指针的值:二级指针,引用,返回值(返回修改后的指针)

[cpp]  view plain  copy
  1. 1传引用/  
  2.   
  3.   /*在主函数中定义树,然后传到createbitree中 
  4. void createbitree(bitnode &t) 
  5. { 
  6.     char ch; 
  7.  
  8.     cin>>ch; 
  9.     if(ch=='#') 
  10.         t=NULL; 
  11.     else 
  12.     { 
  13.         t=new bitnode; 
  14.         //if(!t) 
  15.            // exit(0); 
  16.  
  17.         t->data=ch; 
  18.         createbitree(t->lchild);//构造左子树 
  19.         createbitree(t->rchild);//构造右子树 
  20.     } 
  21. } 
  22. main函数中改为:createbitree(t); 
  23.   
  24.  2 //返回值: 
  25.  
  26.   /*直接在函数中定义树; 
  27. bitnode * createbitree() 
  28. { 
  29.    bitnode *t; 
  30.     char ch; 
  31.  
  32.     cin>>ch; 
  33.     if(ch=='#') 
  34.         t=NULL; 
  35.     else 
  36.     { 
  37.         t=new bitnode; 
  38.         //if(!t) 
  39.            // exit(0); 
  40.  
  41.         t->data=ch; 
  42.         createbitree(t->lchild);//构造左子树 
  43.         createbitree(t->rchild);//构造右子树 
  44.  
  45.   } 
  46.   return t; 
  47. } 
  48.  
  49.   主函数:createbitree(); 
  50.  
  51.  
  52. */  
  53.   
  54. //按前序输入二叉树中结点的值(一个字符)  
  55. //#表示空树,构造二叉链表表示二叉树t《大话数据结构》  
  56. void createbitree(bitnode *(*t))  
  57. {  
  58.     char ch;  
  59.   
  60.     cin>>ch;  
  61.     if(ch=='#')  
  62.        (*t)=NULL;  
  63.     else  
  64.     {  
  65.         (*t)=new bitnode;  
  66.         //if(!t)  
  67.            // exit(0);  
  68.   
  69.         (*t)->data=ch;  
  70.         createbitree(&(*t)->lchild);//构造左子树  
  71.         createbitree(&(*t)->rchild);//构造右子树  
  72.     }  
  73. }  
<think>好的,我现在需要帮助用户解决关于二叉链表实现的二叉树节点统计的问题。首先,用户提到的参考引用中有相关的代码,我需要仔细看一下那段代码的结构。 用户提供的代码里有一个结构体BiTNode,包含data、lchild和rchild,这是典型的二叉树节点结构。然后有CreateBiTree函数用来先序创建二叉树,接着是Count函数,统计不同类型的节点数量。参数a、b、c分别代表叶子节点、度为1的节点和度为2的节点。 用户的问题是询问如何在二叉链表中实现节点统计的算法,可能需要解释这段代码的原理,或者给出更详细的步骤。首先,我需要确认Count函数的工作原理。函数通过递归遍历每个节点,判断其左右子节点的情况。如果左右都存在,c加1;如果只有一个子节点,b加1;如果都没有,a加1。需要注意的是,代码中先递归右子树,再递归左子树,这可能影响遍历顺序,但统计结果应该不受影响,因为顺序不重要,只要所有节点都被访问到。 接下来,我需要思考用户可能的疑问,比如如何区分不同类型的节点,递归的具体过程是怎样的,有没有边界条件需要处理。例如,当节点为空时直接返回,这是递归的终止条件。另外,统计的顺序可能会影响结果,但在这个问题中,只要所有节点都被正确访问,结果应该是准确的。 然后,用户可能需要了解这段代码的使用方法,比如如何初始化a、b、c为0,然后调用Count函数。此外,可能还需要解释如何创建二叉树,使用CreateBiTree函数,传入字符串和索引i。用户可能对字符串表示二叉树的结构有疑问,例如使用'0'表示空节点,其他字符表示有效节点。 在解释算法时,需要分步骤说明:访问当前节点,判断子节点情况,更新计数器,递归处理左右子树。同时,要强调递归是遍历二叉树常用的方法,这里采用先序遍历的方式,但统计节点类型不依赖于遍历顺序,所以中序或后序也可以。 可能的问题点包括:为什么参数a、b、c是引用传递?这是因为在递归过程中需要修改它们的值,保持统计结果的累加。如果使用值传递,每次递归调用都会创建副本,无法正确统计总数。 用户还可能想知道这段代码的时间复杂度和空间复杂度。时间复杂度是O(n),每个节点访问一次;空间复杂度取决于递归深度,最坏情况是O(n)(当树退化为链表时)。 最后,根据用户的要求生成相关问题,可能需要涉及其他统计方法、不同遍历方式的影响、复杂度分析,或者如何扩展该算法来计算其他属性,比如树的高度。同时,用户之前的引用提到了结点个数统计和高度计算,所以相关问题可以包括这些方面。</think>### 基于二叉链表二叉树结点统计算法解析 #### 数据结构定义 二叉链表结点结构定义如下: ```cpp typedef struct BiTNode { char data; struct BiTNode *lchild, *rchild; } BiTNode, *BiTree; ``` #### 结点统计算法实现 通过递归遍历实现三类结点统计: - **叶子结点**(度0):左右子树均为空 - **单分支结点**(度1):左右子树仅有一个非空 - **双分支结点**(度2):左右子树均非空 ```cpp void Count(BiTree T, int &a, int &b, int &c) { if (T == NULL) return; if (T->lchild && T->rchild) // 双分支结点 c++; else if (T->lchild || T->rchild) // 单分支结点 b++; else // 叶子结点 a++; Count(T->lchild, a, b, c); // 递归左子树 Count(T->rchild, a, b, c); // 递归右子树 } ``` #### 算法步骤说明 1. **终止条件**:当前结点为空时直接返回 2. **结点类型判断**: - 左右子结点都存在时,$c$ 计数器+1 - 仅存在一个子结点时,$b$ 计数器+1 - 无子结点时,$a$ 计数器+1 3. **递归遍历**:先左子树后右子树(前序顺序) #### 使用示例 ```cpp int main() { BiTree T; char S[] = "ABD00E00C0F00"; // 二叉树先序序列 int i = 0; CreateBiTree(T, S, i); int a=0, b=0, c=0; Count(T, a, b, c); cout << "叶子结点:" << a << " 单分支:" << b << " 双分支:" << c; } ``` #### 复杂度分析 - 时间复杂度:$O(n)$,每个结点仅访问一次 - 空间复杂度:$O(h)$,递归栈深度与树高$h$相关 [^1]: 参考代码中的`Count`函数通过递归遍历实现了结点分类统计,采用先序遍历顺序,实际可替换为中序/后序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值