求度为k的结点个数
题目描述
假设一棵非空树采用孩子链存储结构,每个结点值均为单个字符。设计一个算法求树中度为k的结点个数。在这个问题中,"度"是指一个结点有多少个子节点。
输入格式
输入的第一行包含两个参数,一个整数 n n n( 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1≤n≤105)表示树中结点的个数,一个字符表示树的根节点。
接下来的 n n n 行,每行包含两个字符,表示树的边,第一个字符是父节点,第二个字符是子节点。
最后一行是一个整数 k k k( 0 ≤ k ≤ n 0 \leq k \leq n 0≤k≤n)表示要查询的结点的度。
输出格式
输出一行,一个整数,表示度为 k k k 的结点的个数。
样例 #1
样例输入 #1
5 A
A B
B C
A D
B E
D F
0
样例输出 #1
3
思路
首先,对当前节点 x
的度数进行检查。如果度数等于 k
,则计数器 cnt
加一;否则,cnt
保持为零。
然后,对当前节点 x
的所有子节点进行遍历。在遍历过程中,对每个子节点 i
调用 countDegreeK(node[x].child[i], k)
,也就是对子节点进行同样的操作。这是一个递归调用,会遍历整棵子树,并将子树中度为 k
的节点数量累加到计数器 cnt
上。
最后,返回计数器 cnt
,这就是树中度为 k
的节点的总数。
算法分析
时间复杂度为 O ( n ) O(n) O(n),因为每个节点都会被访问一次,其中 n n n 是树中节点的总数。
空间复杂度也为 O ( n ) O(n) O(n),因为在最坏的情况下,如果树变成线性结构,递归的深度可能达到 n n n。
AC代码
#include <algorithm>
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
using Status = int;
using ElemType = char;
const int N = 1e6 + 7;
const int M = 1e3 + 7;
const int TRUE = 1;
const int FALSE = 0;
const int OK = 1;
const int ERROR = 0;
const int IMFEASIBLE = -1;
// const int OVERFLOW = -2;
struct TreeNode {
int degree;
int child[M];
} node[M];
int countDegreeK(int x, int k) {
// cout << (char)x << " " << node[x].degree << endl;
int cnt = (node[x].degree == k);
for (int i = 0; i < node[x].degree; i++) {
cnt += countDegreeK(node[x].child[i], k);
}
return cnt;
}
Status addChild(int u, int v) {
if (node[u].degree >= M) {
return ERROR;
}
node[u].child[node[u].degree++] = v;
return OK;
}
int main() {
int n, k;
char root;
cin >> n;
cin >> root;
for (int i = 0; i < n; i++) {
char u, v;
cin >> u >> v;
addChild((int)u, (int)v);
}
cin >> k;
cout << countDegreeK((int)root, k);
return 0;
}