第七章:搜索树🐒
知识点:
-
二叉排序树
-
考点1:已知不同的几个结点,能构成的二叉排序树的形态共有多少种
-
卡特兰数
-
-
构造
-
不同序列可构成同一二叉排序树
-
-
-
平衡二叉树
-
考点1:已知多少结点,求平衡二叉树的最大深度
-
考点2:已知高度,求形态有多少种
-
分析左右子树(拆开)
-
P305,13
-
-
-
概念的应用
-
P307,29、31
-
31题涉及到删除结点后的树不唯一
-
前驱与后继的可替代
-
删去之后,可能导致最小不平衡子树出现,但子树高度相等,两边都能够删除,即不唯一
-
-
-
-
操作
-
插入
-
删除
-
删除图例
-
-
-
Q&A:
1、假设二叉树采用二叉链表存储结构,设计一个算法,求非空二叉树的b的宽度(即具有结点数最多的那一层结点个数)
// 定义二叉树节点结构
struct TreeNode {
int data;
TreeNode* lChild;
TreeNode* rChild;
};
// 计算二叉树的宽度(最大层节点数)
int getMaxWidth(TreeNode* root) {
if (root == null) {
return 0; // 空树宽度为0
}
queue<TreeNode*> q;
q.push(root);
int maxWidth = 0;
while (!q.empty()) {
int currentWidth = q.size(); // 当前层的节点数
// 更新最大宽度
if (currentWidth > maxWidth) {
maxWidth = currentWidth;
}
// 处理当前层的所有节点,并将它们的孩子加入队列
for (int i = 0; i < currentWidth; i++) {
TreeNode* currentNode = q.Dequeue();
if (currentNode->lChild != null) {
q.push(currentNode->lChild);
}
if (currentNode->rChild != null) {
q.push(currentNode->rChild);
}
}
}
return maxWidth;
}
2、假设二叉树采用二叉链表存储结构,设计一个算法,求非空二叉树的编号为i的所处层数
// 定义二叉树节点结构
struct TreeNode {
int data; //data即为编号
TreeNode* lChild;
TreeNode* rChild;
};
// 查找编号为 i 的节点所在的层数
int findLevel(TreeNode* root, int i) {
if (root == null) {
return -1; // 空树返回 -1 表示未找到
}
Queue q;
q.enqueue(root); // 将根节点加入队列
int currentLevel = 1;
while (!q.isEmpty()) {
int levelSize = q.size(); // 计算当前层的节点数
for (int j = 0; j < levelSize; j++) {
TreeNode* currentNode = q.dequeue();
if (currentNode->data == i) {
return currentLevel; // 找到编号为 i 的节点,返回其层数
}
// 将左右孩子加入队列
if (currentNode->lChild != null) {
q.enqueue(currentNode->lChild);
}
if (currentNode->rChild != null) {
q.enqueue(currentNode->rChild);
}
}
currentLevel++;
}
return -1; // 如果遍历完未找到,返回 -1
}
3、请编写一个判别给定二叉树是否为二叉排序树的程序
struct TreeNode {
int data;
TreeNode* lchild;
TreeNode* rchild;
};
// 辅助函数,用来判断二叉树是否为BST
bool judgeBST(TreeNode* T, TreeNode*& prev) {
if (T == null) {
return true; // 空树也是BST
}
// 递归判断左子树
if (!judgeBST(T->lchild, prev)) {
return false;
}
// 当前节点的值应该大于前一个节点的值
if (prev != nullptr && T->data <= prev->data) {
return false;
}
// 更新前一个节点为当前节点
prev = T;
// 递归判断右子树
return judgeBST(T->rchild, prev);
}
4、编写一个输出AVL搜索树中所有结点平衡因子的程序
// 计算树的高度
int height(TreeNode* T) {
if (T == null) {
return 0;
}
int leftHeight = height(T->lChild);
int rightHeight = height(T->rChild);
return max(leftHeight, rightHeight) + 1;
}
// 计算并输出每个节点的平衡因子
void AVLBalance(TreeNode* T) {
if (T == null) {
return;
}
// 计算左右子树的高度
int leftHeight = height(T->lChild);
int rightHeight = height(T->rChild);
// 计算平衡因子
int balanceFactor = leftHeight - rightHeight;
// 输出当前节点和平衡因子
visit(T);
visit(balanceFactor);
// 递归处理左子树和右子树
AVLBalance(T->lChild);
AVLBalance(T->rChild);
}