7-2 列出叶结点 (俺没有测试样例,别想了)

7-2 列出叶结点 (25 分)

对于给定的二叉树,本题要求你按从上到下、从左到右的顺序输出其所有叶节点。

输入格式:

首先第一行给出一个正整数 N(≤10),为树中结点总数。树中的结点从 0 到 N−1 编号。随后 N 行,每行给出一个对应结点左右孩子的编号。如果某个孩子不存在,则在对应位置给出 “-”。编号间以 1 个空格分隔。

输出格式:

在一行中按规定顺序输出叶节点的编号。编号间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6

输出样例:

4 1 5

解题思路:

题目分析:
输入:

以样例为例,输入结点个数为8的一个树,输入的是每个节点的左右孩子,如图
在这里插入图片描述
画出树

在这里插入图片描述
1、4、5为叶子节点
可以发现:叶子节点即输入数据中没有左孩子也没有右孩子的结点

输出:

按“从上到下,从左到右”输出叶子节点

我设定了两个概念:
前驱个数:即该节点的祖先总数
水平位置:在整个树中以树根为中心的相对位置,树根的水平位置为0(作为一个左孩子就-1,右孩子就+1)

水平位置举例:
1节点的水平位置,1节点的祖先是0、2、3,3节点是根其水平位置是0,2结节点是3节点的左孩子,则2节点的水平位置为-1,0节点是2节点的左孩子,则0节点的水平位置为-2,1节点是0节点的左孩子,则1节点的水平位置为-3。
同理4节点的水平位置为0,5节点的水平位置为1。

此时再看输出:
从上到下:所有叶节点中即前驱个数少的先输出
从左到右:所有叶节点中水平位置小的先输出
综述:同等前驱个数,水平位置小的先输出;同等水平位置,前驱个数小的先输出。

解题:

知道了输入是什么,输出是什么,我们要做的就是把输入的树做好处理和保存,然后统计所有叶子结点的前驱个数和水平位置

主要函数:

一、 deal_tree( )

deal_tree( ):处理输入的树并保存的函数,将结果保存在结构体数组tree中

pot:当前节点就是pot节点,1节点,pot即1

input [ ]:保存pot 节点的左右孩子

#define peerless -10000//peerless绝后的,即叶子节点的左右孩子都赋值为peerless

typedef struct tree_node
{
    int node;//当前节点
    int left_c;//左孩子
    int right_c;//又孩子
};

struct tree_node tree[15];

void deal_tree(char *input,struct tree_node *tree,int pot);
void deal_tree(char *input,struct tree_node *tree,int pot)
{
    int i=0;
    while(i<=1)
    {
        if(input[i]=='-')
        {
            if(i==0)
            {
                tree[pot].left_c=peerless;
            }
            else
            {
                tree[pot].right_c=peerless;
            }
        }
        else if(input[i]!='-')
        {
            if(i==0)
            {
                tree[pot].left_c=input[i]-'0';
            }
            else
            {
                tree[pot].right_c=input[i]-'0';
            }
        }
        i++;
    }
}

二、find_leaf( )

find_leaf( ):查找叶子节点,并进行排序和输出

p_l:保存叶子节点以及其前驱个数和水平位置

如何找前驱和确定水平位置:确定叶子节点后,因为结构体下标即叶子节点,通过遍历tree查找它的前驱,并且在查找前驱的时候,确认本身节点的位置,是左孩子则水平位置-1,是右则水平位置+1;每找到一个前驱,就将查找对象赋值为该前驱节点,继续找这个前驱的前驱。

然后排序就行了,完结撒花!

typedef struct pre_level
{
    int node;
    int pre;
    int level;
};

struct pre_level p_l[10];

void find_leaf(struct tree_node *tree,struct pre_level *p_l,int N);

void find_leaf(struct tree_node *tree,struct pre_level *p_l,int N)
{
    int i=0,j=0,k=0,z=0,pre=0,level=0;
    
    while(i<N)
    {
        if(tree[i].left_c==peerless && tree[i].right_c==peerless)
        {//说明 i 节点是叶子节点
            pre=0;
            level=0;
            k=0;
            j=i;
            //查找前驱,确认水平位置
            while(k<N)
            {
                if(tree[k].left_c==j)
                {
                    pre++;
                    level--;
                    //找到前驱后将查找对象提换为该前驱,查找前驱的前驱
                    j=k;
                    k=-1;
                }
                else if(tree[k].right_c==j)
                {
                    pre++;
                    level++;
                    j=k;
                    k=-1;
                }
                k++;
            }
            //printf("%d %d %d\n",i,pre,level);
            p_l[z].node=i;
            p_l[z].pre=pre;
            p_l[z].level=level;
            z++;
        }
        i++;
    }

	//先排前驱,小的在前
    j=0;
    k=0;
    i=0;
    pre=0;
    level=0;
    while(k<z)
    {
        j=k+1;
        while(j<z)
        {
            if(p_l[k].pre>p_l[j].pre)
            {
                i=p_l[k].node;
                pre=p_l[k].pre;
                level=p_l[k].level;

                p_l[k].node=p_l[j].node;
                p_l[k].pre=p_l[j].pre;
                p_l[k].level=p_l[j].level;

                p_l[j].node=i;
                p_l[j].pre=pre;
                p_l[j].level=level;
            }
            j++;
        }
        k++;
    }

	//前驱相同的情况下,水平位置小的在前
    j=0;
    k=0;
    i=0;
    pre=0;
    level=0;
    while(k<z)
    {
        j=k+1;
        while(j<z)
        {
            if(p_l[k].level>p_l[j].level && p_l[k].pre==p_l[j].pre)
            {
                i=p_l[k].node;
                pre=p_l[k].pre;
                level=p_l[k].level;

                p_l[k].node=p_l[j].node;
                p_l[k].pre=p_l[j].pre;
                p_l[k].level=p_l[j].level;

                p_l[j].node=i;
                p_l[j].pre=pre;
                p_l[j].level=level;
            }
            j++;
        }
        k++;
    }

    i=0;
    //这里的注释是为了看看p_l的保存的对不对
    //while(i<z)
    //{
      //  printf("%d %d %d\n",p_l[i].node,p_l[i].pre,p_l[i].level);
        //i++;
    //}

    i=0;
    while(i<z)
    {
        if(i+1!=z)
        {
            printf("%d ",p_l[i].node);
        }
        else
        {
            printf("%d\n",p_l[i].node);
        }
        i++;
    }
}

完整代码:

#include <stdio.h>
#include <math.h>

#define peerless -10000

typedef struct tree_node
{
    int node;//当前节点
    int left_c;//左孩子
    int right_c;//又孩子
};

struct tree_node tree[15];

typedef struct pre_level
{
    int node;
    int pre;
    int level;
};

struct pre_level p_l[10];

void deal_tree(char *input,struct tree_node *tree,int pot);
void find_leaf(struct tree_node *tree,struct pre_level *p_l,int N);

int main()
{
    int N=0,i=0;
    char input[10]="";
    scanf("%d",&N);
    getchar();
    while(i<N)
    {
        scanf("%c %c",&input[0],&input[1]);
        getchar();
        deal_tree(input,tree,i);
        i++;
    }
    find_leaf(tree,p_l,N);
    return 0;
}

void deal_tree(char *input,struct tree_node *tree,int pot)
{
    int i=0;
    while(i<=1)
    {
        if(input[i]=='-')
        {
            if(i==0)
            {
                tree[pot].left_c=peerless;
            }
            else
            {
                tree[pot].right_c=peerless;
            }
        }
        else if(input[i]!='-')
        {
            if(i==0)
            {
                tree[pot].left_c=input[i]-'0';
            }
            else
            {
                tree[pot].right_c=input[i]-'0';
            }
        }
        i++;
    }
}

void find_leaf(struct tree_node *tree,struct pre_level *p_l,int N)
{
    int i=0,j=0,k=0,z=0,pre=0,level=0;
    while(i<N)
    {
        if(tree[i].left_c==peerless && tree[i].right_c==peerless)
        {//说明 i 节点是叶子节点
            pre=0;
            level=0;
            k=0;
            j=i;
            while(k<N)
            {
                if(tree[k].left_c==j)
                {
                    pre++;
                    level--;
                    j=k;
                    k=-1;
                }
                else if(tree[k].right_c==j)
                {
                    pre++;
                    level++;
                    j=k;
                    k=-1;
                }
                k++;
            }
            //printf("%d %d %d\n",i,pre,level);
            p_l[z].node=i;
            p_l[z].pre=pre;
            p_l[z].level=level;
            z++;
        }
        i++;
    }

    j=0;
    k=0;
    i=0;
    pre=0;
    level=0;
    while(k<z)
    {
        j=k+1;
        while(j<z)
        {
            if(p_l[k].pre>p_l[j].pre)
            {
                i=p_l[k].node;
                pre=p_l[k].pre;
                level=p_l[k].level;

                p_l[k].node=p_l[j].node;
                p_l[k].pre=p_l[j].pre;
                p_l[k].level=p_l[j].level;

                p_l[j].node=i;
                p_l[j].pre=pre;
                p_l[j].level=level;
            }
            j++;
        }
        k++;
    }

    j=0;
    k=0;
    i=0;
    pre=0;
    level=0;
    while(k<z)
    {
        j=k+1;
        while(j<z)
        {
            if(p_l[k].level>p_l[j].level && p_l[k].pre==p_l[j].pre)
            {
                i=p_l[k].node;
                pre=p_l[k].pre;
                level=p_l[k].level;

                p_l[k].node=p_l[j].node;
                p_l[k].pre=p_l[j].pre;
                p_l[k].level=p_l[j].level;

                p_l[j].node=i;
                p_l[j].pre=pre;
                p_l[j].level=level;
            }
            j++;
        }
        k++;
    }

    i=0;
    //while(i<z)
    //{
      //  printf("%d %d %d\n",p_l[i].node,p_l[i].pre,p_l[i].level);
        //i++;
    //}

    i=0;
    while(i<z)
    {
        if(i+1!=z)
        {
            printf("%d ",p_l[i].node);
        }
        else
        {
            printf("%d\n",p_l[i].node);
        }
        i++;
    }
}

结果

在这里插入图片描述
额,测试样例我是没有的,因为拼题A改版了,再说了俺是一次过的,要啥测试样例(doge),所以说,就是晒出来秀一下,hei! hei!

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值