鱼C论坛

 找回密码
 立即注册
查看: 2856|回复: 7

[已解决]这样求叶子结点数有错吗?

[复制链接]
发表于 2018-4-25 09:55:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我明明已经定义了leafcount 可是编译器一直提示我第一个leafcount:必须是指向完整对象类型的指针;提示我第二个leafcount:返回值与函数类型不匹配??我不都定义的整型吗???
  1. int leafcount(BiTree T)
  2. {  
  3.         int leafcount=0;
  4.         if(T)
  5.         {
  6.                 if(T->lchild ==NULL &&T->rchild==NULL)
  7.                         leafcount++;
  8.                 leafcount(T->lchild);
  9.                 leafcount(T->rchild);
  10.                 return leafcount;
  11.         }
  12. }
复制代码
最佳答案
2018-4-25 14:07:04
本帖最后由 ABC23 于 2018-4-25 14:09 编辑

问题出在createtree()这个方法。
====================
void creattree(BiTree *T)  //利用递归先序创建二叉树
{
        char ch;
        printf("请输入\n");
        scanf("%c",&ch);
        if(ch=='#')
                (*T)=NULL;
        else
        {
                (*T)=(BiTree)(malloc(sizeof(BiNode)));
                (*T)->data=ch;
                creattree(&(*T)->lchild);
                creattree(&(*T)->rchild);
        }
        printf("二叉树创建完毕\n");
}

在我的机子上跑的结果:

请创建一棵二叉树:
空树构造成功。
请输入
1 2
请输入
请输入
请输入
请输入
#
二叉树创建完毕
请输入
请输入

===================
看到了吗,你在createtree()方法里调用自身,想要创建其两个孩子结点(包括NIL)。
但是,正如上面指出的,本来应该结束的地方并没有结束。
这是我写的:

首先调用initBinaryTree(),创建一棵空树(你的逻辑比较简单,应该判断if 内存不足,抛出创建空树失败),接着为它安排一个data(这不是什么难事);

int insertNode(BiPtr ptr)
{
        BiNode newNode = (BiNode)malloc(sizeof(BiNode));
        if(BiPtr == null)
        {
                print("Out of space!");
                return 1;        // 插入失败,返回1
        }
        print("Enter data as follow.");
        scanf("%d", newNode->data);
        BiPtr pr = ptr;
        while(pr)
        {
                if((pr->leftchild || pr->right) && newNode->data > pr->data)
                {
                        pr = pr->leftchild;
                }
                else if((pr->leftchild || pr->right) && newNode->data > pr->data){
                        pr = pr->rightchild;
                }
                else{
                        print("二叉树不允许有相同元素节点!");
                        return 1;
        }
        pr ->leftchild = &newNode;
        return 0;        // 插入成功,返回0
}

createTree()方法是以insertNode为基础来写的,这样写逻辑比较清晰。

/** ptr是树根,n是想要分配的结点个数(可以自己发挥) */
int createTree(BiPtr ptr, int n)
{
        if(ptr == null)                // 如果是空树
        {
                *ptr = malloc(sizeof(BiNode));        // 就为树根创建一块内存(这里应该if判断下是否成功分配,否早返回1)
                print("Enter data as follow\n");
                scanf("%d", ptr->data);
        }
        while(n--)
        {
                insertNode(ptr);
        }
        return 0;
}

================================

可以看到都是把树根结点(的指针,这样比较轻巧)作为参数传递给二叉树的方法,可以说树根是整棵树的关键节点,掌握了树根也就掌握了整棵树。
22222222.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-4-25 10:32:55 | 显示全部楼层
不要将变量名和函数名重名
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-25 10:35:36 | 显示全部楼层
BngThea 发表于 2018-4-25 10:32
不要将变量名和函数名重名

可是我换成了别的之后,它又说我未定义标识符
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-25 10:48:23 | 显示全部楼层
愿你 发表于 2018-4-25 10:35
可是我换成了别的之后,它又说我未定义标识符

上代码看看,还有具体的错误提示
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-25 10:59:05 | 显示全部楼层
BngThea 发表于 2018-4-25 10:48
上代码看看,还有具体的错误提示
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct BiNode
  4. {
  5.         char data;
  6.         struct BiNode *lchild,*rchild;
  7. }BiNode,*BiTree;

  8. int  inittree(BiTree *T)  //构造空二叉树
  9. {
  10.         (*T)=NULL;
  11.         printf("空树构造成功。\n");
  12.         return 0;
  13. }

  14. void creattree(BiTree *T)  //利用递归先序创建二叉树
  15. {
  16.         char ch;
  17.         scanf("%c",&ch);
  18.         if(ch=='#')
  19.                 (*T)=NULL;
  20.         else
  21.         {
  22.                 (*T)=(BiTree)(malloc(sizeof(BiNode)));
  23.                 (*T)->data=ch;
  24.                 creattree(&(*T)->lchild);
  25.                 creattree(&(*T)->rchild);
  26.         }
  27. }


  28. void preordertree(BiTree T)  //递归先序遍历二叉树
  29. {
  30.         if(T)
  31.         {
  32.                 printf("%c",T->data);
  33.                 preordertree(T->lchild);
  34.                 preordertree(T->rchild);
  35.         }
  36. }
  37. void inordertree(BiTree T)  //递归中序遍历二叉树
  38. {
  39.         if(T)
  40.         {
  41.                 inordertree(T->lchild);
  42.                 printf("%c",T->data);
  43.                 inordertree(T->rchild);
  44.         }
  45. }
  46. void postordertree(BiTree T)  //递归后续遍历二叉树
  47. {
  48.         if(T)
  49.         {
  50.                 postordertree(T->lchild);
  51.                 postordertree(T->rchild);
  52.                 printf("%c",T->data);
  53.         }
  54. }
  55. int isemptytree(BiTree T) //判断二叉树是否为空二叉树
  56. {
  57.         if(T==NULL)
  58.         {
  59.                 printf("该二叉树为空。\n");
  60.                 return 0;
  61.         }
  62.         else
  63.         {
  64.                 printf("该二叉树不为空。\n");
  65.                 return -1;
  66.         }
  67. }

  68. void destroytree(BiTree *T) //递归销毁二叉树,即把包括头的全部节点释放,详见“https://blog.csdn.net/bzhxuexi/article/details/41721429”
  69. {
  70.         if(*T)
  71.         {
  72.                 if((*T)->lchild)
  73.                 {
  74.                         destroytree(&(*T)->lchild);
  75.                 }
  76.                 if((*T)->rchild)
  77.                 {
  78.                         destroytree(&(*T)->rchild);
  79.                 }
  80.                 free(*T);
  81.                 (*T)=NULL; //空指针赋值0;
  82.         }
  83. }

  84. int cleartree(BiTree *T) //清空树,即保留头结点,后面全部释放
  85. {
  86.         if(*T==NULL)
  87.                 return 0;
  88.         else
  89.         {
  90.                 cleartree(&(*T)->lchild);
  91.                 cleartree(&(*T)->rchild);
  92.                 free((*T));
  93.                 return 1;
  94.         }
  95. }

  96. int deeptree(BiTree T)  //求二叉树的深度,递归过程详见“https://blog.csdn.net/tackycheng/article/details/6445916”
  97. {
  98.         int deep=0;
  99.         int ldeep,rdeep;  //左子树深度和右子树深度
  100.         if(T==NULL)
  101.                 return 0;
  102.         else
  103.         {
  104.                 ldeep=deeptree(T->lchild);
  105.                 rdeep=deeptree(T->rchild);
  106.                 deep=ldeep>=rdeep?ldeep+1:rdeep+1;
  107.                 return deep;
  108.         }
  109. }

  110. int nodecount(BiTree T)
  111. {
  112.         int lnode,rnode,node;
  113.         if(T==NULL)
  114.                 return 0;
  115.         else
  116.         {
  117.                 lnode=nodecount(T->lchild);
  118.                 rnode=nodecount(T->rchild);
  119.                 return (lnode+rnode+1);
  120.         }
  121. }

  122. int leafcount(BiTree T)
  123. {
  124.         int lleaf,rleaf,leaf; //分别记录左右子树上的叶子结点总数以及叶子结点总数
  125.         leaf=0;
  126.         if(T==NULL)
  127.                 return 0;
  128.         else
  129.         {
  130.                 lleaf=leafcount(T->lchild);
  131.                 rleaf=leafcount(T->rchild);
  132.                 if(lleaf==0&&rleaf==0)
  133.                         return 1;
  134.                 else
  135.                         return lleaf+rleaf;
  136.         }
  137. }

  138. /*int leafcount(BiTree T)
  139. { &nbsp;
  140.         int count=0;
  141.         if(T)
  142.         {
  143.                 if(T->lchild ==NULL &&T->rchild==NULL)
  144.                         count++;
  145.                 leafcount(T->lchild);
  146.                 leafcount(T->rchild);
  147.                 return count;
  148.         }
  149. }*/

  150. char root(BiTree T) //若树存在,返回树的根。
  151. {
  152.         char e;
  153.         if(T==NULL)
  154.                 return 0;
  155.         else
  156.         {
  157.                 e=T->data;
  158.                 return e;
  159.         }
  160. }















  161. int main()
  162. {
  163.         BiTree T;
  164.         int deep;
  165.         printf("请创建一棵二叉树:\n");
  166.         inittree(&T);
  167.         creattree(&T);
  168.         //deep=deeptree(T);
  169.         //printf("二叉树深度为%d\n",deep);
  170.         //deep=nodecount(T);
  171.         //printf("二叉树结点总数为%d\n",deep);
  172.         deep=root(T);
  173.         printf("二叉树根为%c\n",deep);
  174.         //deep=leafcount(T);
  175.         //printf("二叉树叶子结点总数为%d\n",deep);
  176.         //destroytree(&T);
  177.         //isemptytree(T);
  178.         printf("该二叉树的前序遍历结果为:");
  179.         preordertree(T);
  180.         printf("该二叉树的中序遍历结果为:");
  181.         inordertree(T);
  182.         printf("该二叉树的后序遍历结果为:");
  183.         postordertree(T);
  184.         return 0;
  185. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-25 11:00:13 | 显示全部楼层
BngThea 发表于 2018-4-25 10:48
上代码看看,还有具体的错误提示

代码是leafcount被加注释的那一段
错误提示:1>------ 已启动生成: 项目: 二叉树, 配置: Debug Win32 ------
1>生成启动时间为 2018/4/25 10:58:38。
1>InitializeBuildStatus:
1>  正在创建“Debug\二叉树.unsuccessfulbuild”,因为已指定“AlwaysCreate”。
1>ClCompile:
1>  二叉树.c
1>e:\二叉树\二叉树\二叉树.c(19): warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdio.h(304) : 参见“scanf”的声明
1>e:\二叉树\二叉树\二叉树.c(120): warning C4101: “node”: 未引用的局部变量
1>e:\二叉树\二叉树\二叉树.c(149): error C3872: “0xa0”: 此字符不允许在标识符中使用
1>e:\二叉树\二叉树\二叉树.c(150): error C2065: “&nbsp;”: 未声明的标识符
1>e:\二叉树\二叉树\二叉树.c(150): error C2143: 语法错误 : 缺少“;”(在“类型”的前面)
1>e:\二叉树\二叉树\二叉树.c(154): error C2065: “count”: 未声明的标识符
1>e:\二叉树\二叉树\二叉树.c(157): error C2065: “count”: 未声明的标识符
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-25 14:07:04 | 显示全部楼层    本楼为最佳答案   
本帖最后由 ABC23 于 2018-4-25 14:09 编辑

问题出在createtree()这个方法。
====================
void creattree(BiTree *T)  //利用递归先序创建二叉树
{
        char ch;
        printf("请输入\n");
        scanf("%c",&ch);
        if(ch=='#')
                (*T)=NULL;
        else
        {
                (*T)=(BiTree)(malloc(sizeof(BiNode)));
                (*T)->data=ch;
                creattree(&(*T)->lchild);
                creattree(&(*T)->rchild);
        }
        printf("二叉树创建完毕\n");
}

在我的机子上跑的结果:

请创建一棵二叉树:
空树构造成功。
请输入
1 2
请输入
请输入
请输入
请输入
#
二叉树创建完毕
请输入
请输入

===================
看到了吗,你在createtree()方法里调用自身,想要创建其两个孩子结点(包括NIL)。
但是,正如上面指出的,本来应该结束的地方并没有结束。
这是我写的:

首先调用initBinaryTree(),创建一棵空树(你的逻辑比较简单,应该判断if 内存不足,抛出创建空树失败),接着为它安排一个data(这不是什么难事);

int insertNode(BiPtr ptr)
{
        BiNode newNode = (BiNode)malloc(sizeof(BiNode));
        if(BiPtr == null)
        {
                print("Out of space!");
                return 1;        // 插入失败,返回1
        }
        print("Enter data as follow.");
        scanf("%d", newNode->data);
        BiPtr pr = ptr;
        while(pr)
        {
                if((pr->leftchild || pr->right) && newNode->data > pr->data)
                {
                        pr = pr->leftchild;
                }
                else if((pr->leftchild || pr->right) && newNode->data > pr->data){
                        pr = pr->rightchild;
                }
                else{
                        print("二叉树不允许有相同元素节点!");
                        return 1;
        }
        pr ->leftchild = &newNode;
        return 0;        // 插入成功,返回0
}

createTree()方法是以insertNode为基础来写的,这样写逻辑比较清晰。

/** ptr是树根,n是想要分配的结点个数(可以自己发挥) */
int createTree(BiPtr ptr, int n)
{
        if(ptr == null)                // 如果是空树
        {
                *ptr = malloc(sizeof(BiNode));        // 就为树根创建一块内存(这里应该if判断下是否成功分配,否早返回1)
                print("Enter data as follow\n");
                scanf("%d", ptr->data);
        }
        while(n--)
        {
                insertNode(ptr);
        }
        return 0;
}

================================

可以看到都是把树根结点(的指针,这样比较轻巧)作为参数传递给二叉树的方法,可以说树根是整棵树的关键节点,掌握了树根也就掌握了整棵树。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-4-25 20:57:35 | 显示全部楼层
ABC23 发表于 2018-4-25 14:07
问题出在createtree()这个方法。
====================
void creattree(BiTree *T)  //利用递归先序创建 ...

哇为什么我觉得好难啊
可是我执行creattree的时候他的遍历结果也都是对的呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-16 20:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表