任何疑问、意见、建议请留言公众号:一航代码
题目描述:
从数据结构中树的定义可知,除根节点外,树中的每个节点都有唯一的一个双亲结点。根据这一特性,可用一组连续的存储空间(一维数组)存储树中的各结点。树中的结点除保存本身结点的信息外,还要保存其双亲结点在数组中的位置(即在数组中的下标。双亲的信息为-1则表示该结点为根结点),树的这种表示方法称为双亲表示法。
树中的每个结点的数据类型定义如下:
typedef struct
{
char data; //结点数据域
int parent; //结点双亲在数组中的位置
} PTNode;
树的数据类型定义如下:
#define MAX_TREE_SIZE 100
typedef struct
{
PTNode nodes[MAX_TREE_SIZE]; //存储树中所有的结点
int n; //树中的结点数,n不超过100
} PTree;
如下图所示的树中,按照双亲表示法存储结构,存储为图b所示的形式(n为10)。
已知一棵树以存储以上形式,请编写函数GetLeavesCount,计算叶子结点数目。
GetLeavesCount的函数原型为:
int GetLeavesCount(PTree T);
其中,形参T中保存了树中的结点数目以及图b所示的结点数组,函数返回叶子结点的数目。
输入格式:
输入的第一个数n表示树中的结点数,此后有n行输入,每行表示一个节点的信息,第一个信息为结点的数据,第二个信息为结点的双亲结点在数组中的位置。
输出格式:
比如:对图b的树调用函数GetLeavesCount(T),返回结果为6。
输入样例:
10
a -1
b 0
c 0
d 0
e 1
f 1
g 1
h 2
i 3
h 3
8
a -1
b 0
e 1
h 2
c 0
d 0
f 5
g 5
输出样例:
6
4
解决方法:
(1)代码实现:
#include <iostream>
using namespace std;
#define MAX_TREE_SIZE 100
//公众号:一航代码
typedef struct
{
char data; //结点数据域
int parent; //结点双亲在数组中的位置
} PTNode;
typedef struct
{
PTNode nodes[MAX_TREE_SIZE]; //存储树中所有的结点
int n; //树中的结点数,n不超过100
} PTree;
/*
算法思想:遍历结点数组,当该结点的序号有另外一个节点指向时,
那么该结点为非叶节点,当遍历完结点时,
没有一个结点的指针指向该序号的话,那么该结点即是叶结点。
*/
//返回树中叶结点的个数
int GetLeavesCount(PTree T)
{
int count = 0; //转换一下思考方式,我们统计非叶子节点个数,然后用总结点数减去非叶子结点数
for (int i = 0; i < T.n; i++)
{ //也就是说我们去找i节点有没有孩子节点是j
for (int j = i + 1; j < T.n; j++) //并且对双亲表示法而言,j的孩子下标一定比i大,所以初值设为i+1
{
if (T.nodes[j].parent == i)
{
count++;
break;
}
}
}
return T.n - count;
}
int main()
{
cout << "Please enter the number of nodes:" << endl;
int n = 0;
cin >> n;
PTree pt;
pt.n = n;
cout << "Please enter the data and the position of parent:" << endl;
for (int i = 0; i < n; i++)
{ //输入结点的数据域和结点双亲在数组中的位置
cin >> pt.nodes[i].data >> pt.nodes[i].parent;
}
int leaves = GetLeavesCount(pt);
cout << leaves << endl;
system("pause");
return 0;
}