编程题 03-树2 List Leaves【PAT】

文章目录

编程练习题目集目录

题目

  Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.

输入格式

  Each input file contains one test case. For each case, the first line gives a positive integer N ( ≤ 10 ) N (≤10) N(≤10) which is the total number of nodes in the tree − − -- −− and hence the nodes are numbered from 0 0 0 to N − 1 N−1 N−1. Then N N N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a " − " "-" "−" will be put at the position. Any pair of children are separated by a space.

输出格式

  For each test case, print in one line all the leaves' indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.

输入样例

8

1 -

0 -

2 7

5 -

4 6

输出样例

4 1 5

题解

解题思路

  找到树的根结点,根据树的根结点以及其它一系列结点构建树,按照从上到下,从左到右的顺序(层次遍历)输出这棵树的叶子结点。

完整代码

cpp 复制代码
#include <iostream>         // 包含标准输入输出流库
#include <queue>            // 包含队列数据结构库

using namespace std;        // 使用标准命名空间

#define MaxN  10            // 定义最大节点数量

// 定义二叉树节点结构
struct TreeNode
{
    int Data;           // 节点存储的数据
    int Left;           // 左子节点的索引,若无左子节点则为-2
    int Right;          // 右子节点的索引,若无右子节点则为-2
} TN[MaxN];             // TN[]为全局变量,存储所有节点信息,最多MaxN个节点

int buildTree(TreeNode T[], int n);         // 构建二叉树,并返回根节点索引
void Traversal(int root);                   // 层序遍历二叉树,并输出叶节点值

int main(void)
{
    int N, root;                            // N表示树的节点数量,root表示根节点索引
    cin >> N;
    root = buildTree(TN, N);                // 构建树并获取根节点索引
    Traversal(root);                        // 层序遍历并输出叶节点值
    return 0;
}

// 构建二叉树
int buildTree(TreeNode T[], int n)
{
    int i, check[MaxN];                  // 检查数组,用于标记是否为子节点
    char left, right;                    // 用于存储左右子节点的输入字符
    if (n == 0) {                        // 如果节点数量为0,返回-2表示空树
        return -2;
    }
    for (i = 0; i < n; i++) {           // 初始化所有节点,初始时假设所有节点都不是子节点
        check[i] = -1;                  // -1表示非子节点
        TN[i].Data = i;                 // 每个节点的编号即为自己的数据
    }
    for (i = 0; i < n; i++) {           // 根据输入构建树
        cin >> left >> right;           // 输入当前节点的左右子节点信息
        if (left != '-') {                  // 如果有左子节点
            T[i].Left = left - '0';         // 将字符转换为索引
            check[T[i].Left] = 1;           // 标记左子节点对应的索引为子节点
        }
        else {
            T[i].Left = -2;                 // 表示无左子节点
        }
        if (right != '-') {                 // 如果有右子节点
            T[i].Right = right - '0';       // 将字符转换为索引
            check[T[i].Right] = 1;          // 标记右子节点对应的索引为子节点
        }
        else {
            T[i].Right = -2;                // 表示无右子节点
        }
    }
    // 查找根节点(未被标记为子节点的节点)
    for (i = 0; i < n; i++) {
        if (check[i] == -1) break;          // 找到根节点
    }
    return i;                               // 返回根节点索引
}
// 层序遍历二叉树并输出叶节点值
void Traversal(int root)
{
    queue<struct TreeNode> Q;               // 定义一个队列用于层序遍历
    struct TreeNode T;                      // 临时存储队列中的节点

    if (root == -2) {                       // 如果根节点不存在,直接返回
        return;
    }
    Q.push(TN[root]);                       // 将根节点入队
    int flag = 0;                           // 标志变量,用于控制输出格式
    while (!Q.empty()) {                    // 当队列非空时
        T = Q.front();                      // 取出队列头部节点
        Q.pop();                            // 出队
        if (T.Left == -2 && T.Right == -2) {        // 如果当前节点是叶节点
            if (flag == 1) cout << " ";             // 如果不是第一个叶节点,输出空格
            else flag = 1;                          // 标记已经输出过叶节点
            printf("%d", T.Data);             // 输出叶节点的值
        }
        if (T.Left != -2) {
            Q.push(TN[T.Left]);                     // 如果有左子节点,将左子节点入队
        }
        if (T.Right != -2) {                        // 如果有右子节点,将右子节点入队
            Q.push(TN[T.Right]);
        }
    }
}
相关推荐
David猪大卫11 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
HPtiger11 小时前
C++ 入门笔记:从 C 到 C++ 的核心过渡(命名空间、输入输出、缺省参数、重载、引用、内联)
c语言·c++·学习
努力努力再努力wz14 小时前
【Lua 进阶系列】从 C++ 对象到 Lua 变量:一文理解 userdata、Lua 栈与元表绑定机制
c++·junit·lua
慧都产品智能化14 小时前
Qt 表格升级攻略:复用已有编辑器,减少重复开发
c++·qt·编辑器·qt6.3
ShineWinsu15 小时前
对于Qt:QTableWidget常见属性以及QTableWidgetItem类的解析
开发语言·c++·qt·gui·客户端·表格·qtablewidget
ShineWinsu16 小时前
对于Qt:QListWidget常见属性以及QListWidgetItem类的解析
开发语言·c++·qt·客户端·列表·qlistwidget·qlistwidgetitem
坤坤子吖16 小时前
Linux网络编程:自定义应用层协议与 JSON 序列化
linux·服务器·网络·c++·笔记·json
沫璃染墨17 小时前
从零入门计算机网络系列(十八):TCP连接管理详解——从三次握手与四次挥手到TIME_WAIT机制
运维·服务器·网络·c++·网络协议·tcp/ip·tcp
自信1504130575919 小时前
重生之从0开始学习c++之——vector-中篇
c++·学习·算法
ShineWinsu1 天前
对于Qt:QDial常见属性以及信号的解析
开发语言·c++·qt·gui·客户端·旋钮·qdial