【day3】数据结构刷题 树

R6-1 求二叉树高度

分数 15

函数接口定义:

int GetHeight( BinTree BT );

其中BinTree结构定义如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

要求函数返回给定二叉树BT的高度值。

裁判测试程序样例:
 

#include <stdio.h>
#include <stdlib.h>

typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

BinTree CreatBinTree(); /* 实现细节忽略 */
int GetHeight( BinTree BT );

int main()
{
    BinTree BT = CreatBinTree();
    printf("%d\n", GetHeight(BT));
    return 0;
}
/* 你的代码将被嵌在这里 */

输出样例(对于图中给出的树):

输出为 4 

解答与分析
这个就是所有最优子问题的母题,你看它说的是我们要找出最值,那么我们就可以进行逐步的进行寻找最值就好了,不断地比较左边和右边是哪一个大,当然这可能有点抽象,我们这里要先进行递归到最底部,然后回溯的时候比较哪一个最大,然后进行返回最大的,我们要知道,我们这个是二叉树是从底部哦 
代码

int max(int a, int b){
    if(a > b) return a;
    else return b;
}


int GetHeight(BinTree BT){
    if(BT == NULL) return 0;
    
    int lefthight = GetHeight(BT -> Left);
    int righthight = GetHeight(BT -> Right);
    
    return max(lefthight,righthight) + 1;
}

R6-3 输出二叉树的所有叶子

本题是输出二叉树中的所有叶子结点(默认先左子树后右子树的顺序输出)。

函数接口定义:

void leaf(Bptr p);

裁判测试程序样例:

#include <stdio.h>
#include <malloc.h>
typedef struct node
{
    int data;
    struct node *Lson,*Rson;
}Bnode,*Bptr;

void leaf(Bptr p);//只需完成此函数

Bptr creat();//以扩充先序遍历方式构造二叉树,已构造完成


int main()
{
  Bptr root;    
    root=creat();
  leaf(root);
  return 0;

}

/* 请在这里填写答案 */

输入样例:

3 4 1 0 0 0 2 0 0

输出样例:

输出所有叶子,以一个空格隔开,最后也有一个空格。

1 2 

解析和分析
首先我们要输出所有的子叶节点,那么我们就可以找到子叶的关键,就是左右都是为空的,这个就是子叶,那么就是十分简单的了

void leaf(Bptr p){
    if(p == NULL) return;

    leaf(p -> Lson);
    leaf(p -> Rson);

    if(p -> Lson == NULL && p -> Rson == NULL)
        printf("%d ",p -> data);
}

R6-5 统计二叉树叶子结点个数

本题要求实现一个函数,可统计二叉树的叶子结点个数。

函数接口定义:


int LeafCount ( BiTree T);

T是二叉树树根指针,函数LeafCount返回二叉树中叶子结点个数,若树为空,则返回0。

裁判测试程序样例:


#include <stdio.h>
#include <stdlib.h>

typedef char ElemType;
typedef struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

BiTree Create();/* 细节在此不表 */

int LeafCount ( BiTree T);

int main()
{
    BiTree T = Create();
    
    printf("%d\n", LeafCount(T));
    return 0;
}
/* 你的代码将被嵌在这里 */

输入样例:

输入为由字母和'#'组成的字符串,代表二叉树的扩展先序序列。例如对于如下二叉树,输入数据:

AB#DF##G##C##

输出样例(对于图中给出的树):

二叉树.png

3

 解析和分析
这个就是全局和的母题
首先我们要找到所有的子叶节点的全部个数,那么我们就是要进行再子叶的时候返回1,然后再全部加起来就好了

int LeafCount(BiTree T){
    if(T == NULL) return 0;
    
    if(T -> lchild ==NULL && T -> rchild == NULL) return 1;

    return LeafCount(T -> lchild) + LeafCount(T -> rchild);
}

当然我们还有全部节点的个数的求法,这样就不可以这么写了

int NodeCount(BiTree T){
    if(T == NULL) return 0;
    int sum = NodeCount(T -> lchild)+NodeCount(T -> rchild) + 1;
    return sum;
}

这里我是用一个变量进行存储的,这样是要返回这个变量的,很抽象是不是,其实就是我先进行左子树的遍历,然后再到右子树,然后这个值是一直返回到左子树和右子树的,不断地进行相加求和

R7-1 列出所有祖先结点

对于给定的二叉树,本题要求你按从上到下顺序输出指定结点的所有祖先结点。

输入格式:

首先第一行给出一个正整数 N(≤10),为树中结点总数。树中的结点从 0 到 N−1 编号。

随后 N 行,每行给出一个对应结点左右孩子的编号。如果某个孩子不存在,则在对应位置给出 "-"。编号间以 1 个空格分隔。

最后一行给出一个结点的编号i(0≤i≤N-1)。

输出格式:

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

输入样例:

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

输出样例:

3 5

解答和分析
我们可以进行深度优先,找到这个节点第几行,然后再重新进行依次遍历,找打这个行数所在地父节点

#include <stdio.h>

int n = 0;
char a[10][2];
int ans[10];
int num = 0;
int key;

void dfs(int x) {
    for (int i = 0; i < 2; i++) {
        if (a[x][i] != '-' && (a[x][i] - '0') == key) {
            ans[num++] = x;
            key = x;
            dfs(0);
            return;
        }
    }
    if (x + 1 < n) {
        dfs(x + 1);
    }
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf(" %c %c", &a[i][0], &a[i][1]);
    }
    scanf("%d", &key);

    dfs(0);  // 从根结点0开始查找
    int first = 0;
    for (int i = num-1; i >= 0; i--) {
        if(first == 0){
            first = 1;
            printf("%d",ans[i]);
        }
        else
        printf(" %d", ans[i]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值