仲舟のMOOC第七周编程作业

///*题目:树的基本运算
///*作者:仲舟                                       
///*难度:★★★
///*完成时间:2021.04.27
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define m 3
#define MAXLEN 100

typedef char datatype;
typedef struct node {
    datatype data;
    struct node *child[m];
} node;
typedef  node *tree;

tree  CreateTree(); /*按前序遍历顺序建立一棵3度树,返回树根地址  */
void LevelOrder(tree t);    /* t为指向树根结点的指针,输出树的层次遍历序列*/
void PreOrder(tree t);    /* t为指向树根结点的指针,输出树的前序遍历序列*/
void PostOrder(tree t); /* t为指向树根结点的指针,输出树的后序遍历序列*/
int main() {
    tree t;
    t=CreateTree();
    printf("\nthe LevelOrder is:");
    LevelOrder(t);
    printf("\nthe PreOrder is:");
    PreOrder(t);
    printf("\nthe PostOrder is:");
    PostOrder(t);
    return 0;
}
tree  CreateTree() {
    int i;
    char ch;
    tree t;
    if ((ch=getchar())=='#')  t=NULL;
    else {
        t=(tree) malloc (sizeof(node));
        t->data=ch;
        for (i=0; i<m; ++i)
            t->child[i]= CreateTree();
    }
    return t;
}

void LevelOrder(tree t) { /* t为指向树根结点的指针,输出树的层次遍历序列*/
    /*仲舟猜测:层次遍历是访问一层中的所有结点,而递归是不断访问子结点,所以用递归无法实现层次遍历,层级访问只需用循环即可*/
    /*层次遍历可以理解为:树由高到低,高层的比低层的年纪大,左层比右层年纪大,只要按年纪大小从大到小排列输出就说层次排列,
    为了更好理解,下面做个《细胞分裂》游戏,队列用“按年龄从大到小排列的活细胞”表示,每个细胞的寿命都一样,当他死后即细胞分裂,会分裂出新生细胞*/
    tree queue[MAXLEN],die;//队列(用于按年龄从大到小排列),将要死亡的细胞
    int l,r;//队列最左下标、队列最右下标
    r=l=0;//初始化
    queue[r++]=t;//原生细胞入队
    while(l<r)//队列还有就执行
    {
        die=queue[l++];//最左边的那个细胞将要死了
        printf("%c",die->data);//先把它刻在墓碑上(输出)
        for(int i=0;i<=m-1;i++)//再计算它分了几个细胞
        if(die->child[i]!=NULL)//如果分裂了
            queue[r++]=die->child[i];//它的孩子入队
    }
}

void PreOrder(tree t)    /* t为指向树根结点的指针,输出树的前序遍历序列*/
{
    if(t->data!='#') { //如果不为空
        printf("%c",t->data);//先输出老子
        for(int i=0; i<=m-1; i++) //再找孩子
        if(t->child[i])//如果有孩子
            PreOrder(t->child[i]);
    }
    //如果空,则终止递归
}

void PostOrder(tree t) /* t为指向树根结点的指针,输出树的后序遍历序列*/
{
    if(t->data!='#') { //如果不为空
        for(int i=0; i<=m-1; i++) //先找孩子
        if(t->child[i])
            PostOrder(t->child[i]);
        printf("%c",t->data);//再输出老子
    }
    //如果空,则终止递归
}

///*题目:求树中叶子结点的个数以及树t中结点值为x的结点的层号
///*作者:仲舟                                       
///*难度:★★
///*完成时间:2021.04.27
#include <stdlib.h>
#include <malloc.h>
#define m 3
#define MAXLEN 20

typedef char datatype;
typedef struct node {
     datatype data;
     struct node *child[m];
} node;
typedef  node *tree;

tree  CreateTree(); /*按前序遍历顺序建立一棵3度树,返回树根地址 */
int LeafNodes(tree t);    /* 求树t中叶子结点的个数,返回值为叶子结点个数*/
int Level(tree t,datatype x,int h);
/* 求树t中结点值为x的结点的层号,h为辅助参数,记录树t的层号,
返回值为结点值为x的结点层号,假设根结点的层号为1。
若树t中不存在结点值为x的结点,返回0*/

int main()
{
   int N,level;
   datatype ch;
   tree t;
   t=CreateTree();
   printf("\nthe LeafNodes is:%d\n",LeafNodes(t));
   scanf("%d",&N);getchar();
   while(N--){
        scanf("%c",&ch);getchar();
        level=Level(t,ch,1);
        if (level==0) printf("the node %c is not exist.\n",ch);
        else printf("the level of the node %c is %d\n",ch,level);
   }
   return 0;
}
tree  CreateTree()
 {
   int i;
   char ch;
   tree t;
   if ((ch=getchar())=='#')  t=NULL;
   else{
        t=(tree) malloc (sizeof(node));
        t->data=ch;
        for (i=0;i<m;++i)
            t->child[i]= CreateTree();
    }
   return t;
}

/*仲舟提示:用递归思想:假设我这个LeafNodes(t)函数能用,它返回值的应该是下一个孩子树它所带有的结点,我要把这个值返回给它父亲,应该是return LeafNodes(t孩子),这是我一层该做的事,如果每个函数都像我一样,那么就可以完成整个任务*/
int LeafNodes(tree t)    /* 求树t中叶子结点的个数,返回值为叶子结点个数*/
{
    if(t)//如果t存在
    {
        if(!t->child[0]&&!t->child[1]&&!t->child[2])//并且它的孩子都没有,即它是叶结点
           return 1;//终止递归,返回1,表示找到了一个结点
        else//如果有孩子
           return LeafNodes(t->child[0])+LeafNodes(t->child[1])+LeafNodes(t->child[2]);//要返回把三个孩子的树的叶结点加起来,继续递归
    }
    else//如果t不存在
        return 0;
}

int Level(tree t,datatype x,int h)
/* 求树t中结点值为x的结点的层号,h为辅助参数,记录树t的层号,
返回值为结点值为x的结点层号,假设根结点的层号为1。
若树t中不存在结点值为x的结点,返回0*/
{
    if(t)//如果t存在
    {
        if(t->data==x)//如果找到
        return h;//返回层数
    else//如果没找到
        return Level(t->child[0],x,h+1)+Level(t->child[1],x,h+1)+Level(t->child[2],x,h+1);//再找三个孩子有没有,层数+1
    }
    else//如果t不存在
        return 0;
}

仲舟原创,未经允许禁止转载!

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值