东华大学上机题——计算叶子节点数目
题目描述:
从数据结构中树的定义可知,除根节点外,树中的每个节点都有唯一的一个双亲结点。根据这一特性,可用一组连续的存储空间(一维数组)存储树中的各节点。树中的结点除保存本身结点的信息外,还要保存其双亲结点在数组中的位置(即在数组中的下标。双亲的信息为-1则表示该结点为根节点),树的这种表示方法称为双亲表示法。
树中的每个结点的数据类型定义如下:
struct PTNode{
char data;//结点数据域
int parent;//结点双亲在数组中的位置
};
树的数据类型定义如下:
#define MAX_TREE_SIZE 100
struct PTree {
PTNode nodes[MAX_TREE_SIZE];//存储树中的所有结点
int n;//树中的结点数,n不超过100
};
则下图所示的树中,按照双亲表示法存储结构,存储为下图所示的形式(n为10)。
已知一棵树已存储以上形式,请编写函数GetLeavesCount,计算叶子节点数目。
GetLeavesCount的函数原型为:int GetLeavesCount(PTree T)
其中,形参T中保存了树中节点数目以及图b所示的结点数组,函数返回叶子结点的数目。
比如:对图中的数调用函数GetLeavesCount(T),返回结果为6
输入的第一个数n表示树中的结点数,此后有n行输入,每行表示一个结点的信息,第一个信息为结点的数据,第二个信息为结点的双亲结点在数组中的位置。
如输入:
10
a -1
b 0
c 0
d 0
e 1
f 1
g 1
h 2
i 3
h 3
则创建图中对应的数。
对此树调用函数GetLeavesCount(T),返回结果为6.
如输入:
8
a -1
b 0
e 1
h 2
c 0
d 0
f 5
g 5
对此树调用GetLeavesCount(T),返回结果为4
算法思想:
遍历结点数组,当该结点的序号有另外一个结点指向时,那么该结点为非叶子结点,当遍历完结点时,没有一个结点的指针指向该序号的话,那么该结点即使叶节点。这里转换一下思考方式,统计非叶子结点的个数会更容易一点。
#include<iostream>
using namespace std;
struct PTNode{
char data;//结点数据域
int parent;//结点双亲在数组中的位置
};
#define MAX_TREE_SIZE 100
struct PTree {
PTNode nodes[MAX_TREE_SIZE];//存储树中的所有结点
int n;//树中的结点数,n不超过100
};
int GetLeavesCount(PTree T) {
int count = 0;//用来存储非叶子结点的个数
for (int i = 0;i < T.n;i++) {
for (int j = 0;j < T.n;j++) {
if (i == j)
continue;//自己不和自己比较
if (i == T.nodes[j].parent) {//检测到该结点有叶子结点
count++;//非叶子结点数增加
break;//不重复计算该结点
}
}
}
return T.n - count;//返回叶子结点数
}
int main() {
int n;
cout << "输入结点个数:";
cin >> n;
PTree T;
T.n = n;
cout << "输入结点信息:" << endl;
for (int i = 0;i < n;i++) {
cin >> T.nodes[i].data >> T.nodes[i].parent;
}
cout << "叶子结点个数为:" << GetLeavesCount(T) << endl;
return 0;
}
运行测试结果: