5章习题 P157
5.1画出由4个结点所构成的所有形态的树(假设是无序树)。
A A A A A A
/|\ /|\ /|\ /|\ /|\ /|\
B C D B D C C B D C D B D B C D C B
5.2已知一棵树的度为4,其中度为4的结点的数目为3,度为3的结点的数目为4,度为2的结点的数目为5,度为1的结点的数目为2,请求出该树中的叶子结点的数目。
(数目是23)
5.4已知某完全二叉树有100个结点,试用三种不同的方法求出该二叉树的叶子结点数。
方法一:通过计算
由于完全二叉树的性质,该树的叶子结点要么在最后一层,要么在倒数第二层。我们可以计算最后一层和倒数第二层的结点数目,然后相加得到叶子结点数目。
最后一层的结点数目 = 总结点数目 % 2^(树的高度-1)
最后一层的结点数目 = 100 % 2^(7-1)
最后一层的结点数目 = 100 % 64
最后一层的结点数目 = 36
倒数第二层的结点数目 = 2^(树的高度-2)
倒数第二层的结点数目 = 2^(7-2)
倒数第二层的结点数目 = 2^5
倒数第二层的结点数目 = 32
叶子结点数目 = 最后一层的结点数目 + 倒数第二层的结点数目
叶子结点数目 = 36 + 32
叶子结点数目 = 68
方法二:通过性质
对于一个完全二叉树,如果总结点数目为n,叶子结点数目为m,则有以下关系:
m = (n + 1) / 2
叶子结点数目 = (总结点数目 + 1) / 2
叶子结点数目 = (100 + 1) / 2
叶子结点数目 = 101 / 2
叶子结点数目 = 50.5 (四舍五入为最近的整数)
叶子结点数目 = 51
方法三:通过层数
对于一个完全二叉树,如果树的高度为h,叶子结点数目为m,则有以下关系:
m = 2^(h-1)
树的高度h可以通过以下方式计算:
h = log2(总结点数目) + 1
树的高度h = log2(100) + 1
树的高度h ≈ 6.643 + 1
树的高度h ≈ 7.643 (向上取整到最近的整数)
树的高度h = 8
叶子结点数目 = 2^(树的高度-1)
叶子结点数目 = 2^(8-1)
叶子结点数目 = 2^7
叶子结点数目 = 128
因此,通过三种不同的方法计算,该完全二叉树的叶子结点数目为68、51和128。
5.7设计算法以求解编号为i和j的两个结点的最近的公共祖先结点的编号。
// 找到从根节点到目标节点的路径
bool findPath(Node* root, int target, vector<Node*>& path) {
if (root == nullptr)
return false;
path.push_back(root);
if (root->val == target)
return true;
if (findPath(root->left, target, path))
return true;
if (findPath(root->right, target, path))
return true;
path.pop_back();
return false;
}
// 找到具有编号i和j的两个节点的最近公共祖先节点
int findLowestCommonAncestor(Node* root, int i, int j) {
vector<Node*> pathToI;
vector<Node*> pathToJ;
if (!findPath(root, i, pathToI) || !findPath(root, j, pathToJ))
return -1; // 节点不存在
int ancestor = root->val;
// 比较路径,找到最后一个相同的节点
for (int k = 0; k < min(pathToI.size(), pathToJ.size()); k++) {
if (pathToI[k] == pathToJ[k])
ancestor = pathToI[k]->val;
else
break;
}
return ancestor;
}
5.8分别求出下图中二叉树的三种遍历序列。
屏幕截图 2024-04-22 215832.png
A:先ABCDEFGHIJ中CDBEFAHGJI后DCFEBHJIGA
B;先ABCDE中EDCBA后EDCBA
C:先ABCDE中BDECA后EDCBA
D:先ABCDE中ABCDE后EDCBA
5.9分别描述满足下面条件的二叉树特征:
(1)先序序列和中序序列相同:
如果先序序列和中序序列相同,那么这个二叉树必须是一棵只有根节点的树。因为在先序遍历中,根节点首先被访问,而在中序遍历中,根节点在左子树之前被访问。因此,如果先序序列和中序序列相同,那么树中只有一个节点,即根节点。
(2)先序序列和后序序列相反:
如果先序序列和后序序列相反,那么这个二叉树必须是一棵只有根节点的树。因为在先序遍历中,根节点首先被访问,而在后序遍历中,根节点在左子树和右子树之后被访问。因此,如果先序序列和后序序列相反,那么树中只有一个节点,即根节点。