中国大学MOOC-数据结构基础习题集、03-2、List Leaves

首先贴一下题目:

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

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=10) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N-1. Then 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.

Output Specification:

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.

Sample Input:

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

Sample Output:

4 1 5

简单分析一下:

  输入的第一行,是一个整数n,是节点的个数(≤10)。接下来是n行,每一行有两个数a和b,用来说明左孩子和有孩子是第几个节点。如果为空用‘-’表示。如第1行(准确说第0行)的a、b值分别是1和-,就是说标号为0的节点左孩子是标号为1的节点,右孩子为空。

  输出的一行,是所有的叶子节点,要求从上到下,从左到右输出。

  这道题应该分为两大步,第一步是建树,第二步是层次遍历。有的同学(比如我),发现了左右孩子都为‘-’为叶子节点,直接输出不就可以了?其实不是这样的,如果那样输出的顺序不对。因为题中要求了必须从上到下,从左到右输出。

先说说我的解题思路吧:

1. 首先定义两个结构体,一个是BinTreeNode(用于表示二叉树节点),一个是myNode(用于接收输入的数据)。template <class T>是模板,T是类型。使用方式如下:BinTreeNode<int> *root;。如果把模板去掉,T换成int,也可以,形如:BinTreeNode *root;。

 1 template <class T>
 2 struct BinTreeNode
 3 {
 4     BinTreeNode<T> *left;
 5     BinTreeNode<T> *right;
 6     T data;
 7     BinTreeNode(T d, BinTreeNode<T> *l, BinTreeNode<T> *r)
 8     {
 9         data = d;
10         left = l;
11         right = r;
12     }
13 };
14
15 typedef struct myNode
16 {
17     int left;
18     int right;
19     myNode(int l, int r):
20         left(l), right(r)
21     {
22
23     }
24 }myNode;

2. 接下来是输入。这里我们仍然用的是vector,之前看过其他几篇博客的人知道,博主是十分喜欢vector的,主要原因是其他的还不太会用……。

 1 int main()
 2 {
 3     // 用到的数据结构
 4     vector<myNode> vec;
 5     vector<BinTreeNode<int> > res;
 6     // 先输入一个整数
 7     int n;
 8     cin >> n;
 9     // 再输入n行数据
10     char a, b;
11     for(int i=0; i<n; i++)
12     {
13         cin >> a >> b ;
14         vec.push_back(myNode(a, b));
15     }
16     // ...

3. 下面开始建树了,首先要生成n个节点,接下来通过输入的信息把指针域“拼接”起来。

 1     // 生成树的n个结点,放进vector里
 2     for(int i=0; i<n; i++)
 3     {
 4         res.push_back(BinTreeNode<int>(i, NULL, NULL));
 5     }
 6     // 建树
 7     for(int i=0; i<n; i++)
 8     {
 9         if(vec[i].left != ‘-‘)
10         {
11             res[i].left = &res[vec[i].left - ‘0‘];
12         }
13         else
14         {
15             res[i].left = NULL;
16         }
17         if(vec[i].right != ‘-‘)
18         {
19             res[i].right = &res[vec[i].right - ‘0‘];
20         }
21         else
22         {
23             res[i].right = NULL;
24         }
25     }

4. 在这一步骤,我们需要找到树的根在哪。我的方法是:建一个大小为n的bool数组flag,初值为均为0。如果出现在输入里的节点,肯定不是根节点,对应的flag变为1。剩下来那一个为0的肯定就是根节点了。

 1     // bool型数组帮助找到根节点
 2     vector<bool> flag;
 3     // 树的根节点
 4     BinTreeNode<int> * root = NULL;
 5     // 找到根节点,flag仍然为0的那个就是,当然这里还没有给head赋值
 6     for(int i=0; i<n; i++)
 7     {
 8         flag.push_back(0);
 9     }
10     for(int i=0; i<n; i++)
11     {
12         if(vec[i].left != ‘-‘)
13             flag[vec[i].left-‘0‘] = 1;
14         if(vec[i].right!= ‘-‘)
15             flag[vec[i].right-‘0‘] = 1;
16     }
17
18     for(int i=0; i<n; i++)
19     {
20         if(flag[i] == 0)
21         {
22             root = &res[i];
23             break;
24         }
25     }

5. 借助队列进行层次遍历:首先根节点入队,然后循环进行如下步骤:出队、出队的节点的左右孩子依次入队(如果存在的话)、如果出队的节点是叶子节点(即左右孩子均为空)则把这个节点的data域放进名为result的vecotr里。

 1     BinTreeNode<int> * p;
 2     vector<int> result;
 3     queue<BinTreeNode<int> *> que;
 4     que.push(root);
 5
 6     while(p != NULL)
 7     {
 8         if(que.size() == 0)
 9             break;
10         p = que.front();
11         if(p -> left == NULL && p -> right == NULL)
12         {
13             result.push_back(p->data);
14         }
15         que.pop();
16         if(p -> left != NULL)
17         {
18             que.push(p -> left);
19         }
20         if(p -> right != NULL)
21         {
22             que.push(p -> right);
23         }
24     }

6. 输出结果,最后一个空格不要有哦!

1     int len = result.size();
2     for(int i=0; i<len ; i++)
3     {
4         cout << result[i];
5         if(i != len - 1)
6             cout << " ";
7     }
8     return 0;
9 }

7. 完整的代码:

  1 #include <iostream>
  2 #include <vector>
  3 #include <queue>
  4 using namespace std;
  5
  6 template <class T>
  7 struct BinTreeNode
  8 {
  9     BinTreeNode<T> *left;
 10     BinTreeNode<T> *right;
 11     T data;
 12     BinTreeNode(T d, BinTreeNode<T> *l, BinTreeNode<T> *r)
 13     {
 14         data = d;
 15         left = l;
 16         right = r;
 17     }
 18 };
 19
 20 typedef struct myNode
 21 {
 22     int left;
 23     int right;
 24     myNode(int l, int r):
 25         left(l), right(r)
 26     {
 27
 28     }
 29 } myNode;
 30
 31 int main()
 32 {
 33     // 用到的数据结构
 34     vector<myNode> vec;
 35     vector<BinTreeNode<int> > res;
 36     // 先输入一个整数
 37     int n;
 38     cin >> n;
 39     // 再输入n行数据
 40     char a, b;
 41     for(int i=0; i<n; i++)
 42     {
 43         cin >> a >> b ;
 44         vec.push_back(myNode(a, b));
 45     }
 46     // 生成树的n个结点,放进vector里
 47     for(int i=0; i<n; i++)
 48     {
 49         res.push_back(BinTreeNode<int>(i, NULL, NULL));
 50     }
 51     // 建树
 52     for(int i=0; i<n; i++)
 53     {
 54         if(vec[i].left != ‘-‘)
 55         {
 56             res[i].left = &res[vec[i].left - ‘0‘];
 57         }
 58         else
 59         {
 60             res[i].left = NULL;
 61         }
 62         if(vec[i].right != ‘-‘)
 63         {
 64             res[i].right = &res[vec[i].right - ‘0‘];
 65         }
 66         else
 67         {
 68             res[i].right = NULL;
 69         }
 70     }
 71     // bool型数组帮助找到根节点
 72     vector<bool> flag;
 73     // 树的根节点
 74     BinTreeNode<int> * root = NULL;
 75     // 找到根节点,flag仍然为0的那个就是,当然这里还没有给head赋值
 76     for(int i=0; i<n; i++)
 77     {
 78         flag.push_back(0);
 79     }
 80     for(int i=0; i<n; i++)
 81     {
 82         if(vec[i].left != ‘-‘)
 83             flag[vec[i].left-‘0‘] = 1;
 84         if(vec[i].right!= ‘-‘)
 85             flag[vec[i].right-‘0‘] = 1;
 86     }
 87
 88     for(int i=0; i<n; i++)
 89     {
 90         if(flag[i] == 0)
 91         {
 92             root = &res[i];
 93             break;
 94         }
 95     }
 96
 97     BinTreeNode<int> * p;
 98     vector<int> result;
 99     queue<BinTreeNode<int> *> que;
100     que.push(root);
101
102     while(p != NULL)
103     {
104         if(que.size() == 0)
105             break;
106         p = que.front();
107         if(p -> left == NULL && p -> right == NULL)
108         {
109             result.push_back(p->data);
110         }
111         que.pop();
112         if(p -> left != NULL)
113         {
114             que.push(p -> left);
115         }
116         if(p -> right != NULL)
117         {
118             que.push(p -> right);
119         }
120     }
121     int len = result.size();
122     for(int i=0; i<len ; i++)
123     {
124         cout << result[i];
125         if(i != len - 1)
126             cout << " ";
127     }
128     return 0;
129 }

按照惯例粘一下AC的结果:

时间: 2024-11-23 06:13:39

中国大学MOOC-数据结构基础习题集、03-2、List Leaves的相关文章

中国大学MOOC-陈越、何钦铭-数据结构基础习题集 03-1. 二分法求多项式单根

03-1. 二分法求多项式单根(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 杨起帆(浙江大学城市学院) 二分法求函数根的原理为:如果连续函数f(x)在区间[a, b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个根r,即f(r)=0. 二分法的步骤为: 检查区间长度,如果小于给定阈值,则停止,输出区间中点(a+b)/2:否则 如果f(a)f(b)<0,则计算中点的值f((a+b)/2): 如

Python网络爬虫与信息提取(中国大学mooc)

目录 目录 Python网络爬虫与信息提取 淘宝商品比价定向爬虫 目标获取淘宝搜索页面的信息 理解淘宝的搜索接口翻页的处理 技术路线requests-refootnote 代码如下 股票数据定向爬虫 列表内容 爬取网站原则 代码如下 代码优化 Python网络爬虫与信息提取 淘宝商品比价定向爬虫 股票数据定向爬虫 1. 淘宝商品比价定向爬虫 功能描述 目标:获取淘宝搜索页面的信息 理解:淘宝的搜索接口翻页的处理 技术路线:requests-re[^footnote]. 代码如下: #CrowTa

使用selenium + chrome爬取中国大学Mooc网的计算机学科的所有课程链接

目的:使用selenium + chrome爬取中国大学Mooc网计算机学科的所有的课程链接列表 思路:找到每个分页的节点属性为class="m-course-list" 的div元素,再找到该元素下面的类属性为class = "u-clist f-bg f-cb f-pr j-href ga-click"的div元素的属性data-href的值,使用xpath获取. 难点:在网页源码里面,是看不到相关的课程链接信息,点击分页,发现地址栏的url一直都在变,但改变u

中国大学MOOC 哈工大数据库系统 第8讲模拟练习题答案

完整 中国大学MOOC 哈工大数据库系统 第8讲模拟练习题答案.pdf, 点我下载,进入下载页面点击普通下载 SQL语言的GRANT和REVOKE语句主要是用来维护数据库的_________. A.安全性 B.完整性 C.可靠性 D.一致性 正确答案:A你选对了 2安全性控制的防范对象是_________,防止他们对数据库数据的存取. A.非法非授权用户 B.不符合语义的数据 C.不正确的数据 D.不符合约束的数据 正确答案:A你选对了 原文地址:https://www.cnblogs.com/

Mooc数据结构-基础和线性结构

1 数据结构 解决问题方法的效率,跟数据的组织方式有关 解决问题方法的效率,跟空间的利用效率有关 解决问题方法的效率,跟算法的巧妙程度有关 数据结构 数据对象在计算机中的组织方式 逻辑结构 物理存储结构 数据对象必定与一系列加在其上的操作相关联 完成这些操作所用的方法就是算法 抽象数据类型(Abstract Data Type) 数据类型 数据对象集 数据集合相关联的操作集 抽象: 描述数据类型的方法不依赖与具体实现 与存放数据的机器无关 与数据存储的物理结构无关 与实现操作的算法和编程语言无关

中国大学mooc程序设计入门——C语言:第三周测验

1.奇偶个数(5分) 题目内容: 你的程序要读入一系列正整数数据,输入-1表示输入结束,-1本身不是输入的数据.程序输出读到的数据中的奇数和偶数的个数. 输入格式: 一系列正整数,整数的范围是(0,100000).如果输入-1则表示输入结束. 输出格式: 两个整数,第一个整数表示读入数据中的奇数的个数,第二个整数表示读入数据中的偶数的个数.两个整数之间以空格分隔. 输入样例: 9 3 4 2 5 7 -1 输出样例: 4 2 时间限制:500ms内存限制:32000kb 参考代码: 1 #inc

中国大学MOOC 玩转AutoCAD 熟悉AutoCAD的人机交互方式

中国大学MOOC | C语言程序设计入门 第8周编程练习 翁恺

1 单词长度(4分) 题目内容: 你的程序要读入一行文本,其中以空格分隔为若干个单词,以‘.’结束.你要输出这行文本中每个单词的长度.这里的单词与语言无关,可以包括各种符号,比如“it's”算一个单词,长度为4.注意,行中可能出现连续的空格. 输入格式: 输入在一行中给出一行文本,以‘.’结束,结尾的句号不能计算在最后一个单词的长度内. 输出格式: 在一行中输出这行文本对应的单词的长度,每个长度之间以空格隔开,行末没有最后的空格. 输入样例: It's great to see you here

中国大学MOOC 浙江大学 C语言程序设计进阶 翁恺 自拟题解

第一章 题目: 字符串比对 题目内容: 题目说起来很简单,你会读到两个字符串,每个字符串占据一行,每个字符串的长度均小于10000字符,而且第一个字符串的长度小于第二个字符串的.你的程序要找出第一个字符串在第二个字符串中出现的位置,输出这些位置,如果找不到,则输出-1. 注意,第一个字符的位置是0. 注意,第一个字符串在第二个字符串中的位置可能不止一处. 注意,字符串中可能含有空格. 注意,两个字符串的长度一定大于0. 输入格式: 两个字符串,一行一个. 输出格式: 第一个字符串在第二个字符串中

中国大学MOOC-翁恺-C语言程序设计习题集

Technorati 标签: 中国大学MOOC-翁恺-C语言程序设计习题集,C 今年网易出了"中国大学MOOC",于是选了浙大翁恺老师的"C语言程序设计"学习,近期打算把自己在该课程中的PAT习题解答做一个记录,等自己编程能力提高后再来看现在写的代码哪里还有写的不好,可以改进的地方,达到反思的目的.   中国大学MOOC-翁恺-C语言程序设计习题集,布布扣,bubuko.com