本节课实验课总体安排:
1、讲解4道选择题;
2、讲解平衡二叉树的构造,输出二叉树的中序遍历序列,判断该二叉树是否为平衡二叉树;
3、完成两道力扣题:二叉树的中序遍历+平衡二叉树的判断
一、选择题
1、【历年期末试题】设散列表表长 m =14,散列函数 H(K)= k mod 11,表中已经有15、38、61、84四个元素,如果用线形探测法处理冲突,则元素49的存储地址是()
✅ 计算 49 的初始散列地址
散列函数:
[H(k) = k mod 11]
[49 mod 11 = 49 - 44 = 5]
初始地址 = 5
✅ 查看表中已有元素的地址
| 元素 | (k \mod 11) | 地址 |
|---|---|---|
| 15 | 15 mod 11 = 4 | 4 |
| 38 | 38 mod 11 = 5 | 5 |
| 61 | 61 mod 11 = 6 | 6 |
| 84 | 84 mod 11 = 7 | 7 |
占用地址:4, 5, 6, 7
✅ 用线性探测法查找下一个空位置
49 初始地址:5
-
地址 5:被 38 占用 → 冲突
-
地址 6:被 61 占用 → 冲突
-
地址 7:被 84 占用 → 冲突
-
地址 8:空位
🎯最终结果:49 的存储地址 = 8
2、 折半查找有序表(4,6,10,12,20,30,50,70,88,100)。若查找表中元素58,则它将依次与表中()比较大小,查找结果是失败。
✅ 有序表
索引(0~9)对应表中元素:
| 下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| 元素 | 4 | 6 | 10 | 12 | 20 | 30 | 50 | 70 | 88 | 100 |
🔍 开始折半查找 58
① 第一次比较
low = 0, high = 9
mid = (0 + 9) / 2 = 4
比较元素:20
58 > 20 → 去右半段(5~9)
② 第二次比较
low = 5, high = 9
mid = (5 + 9) / 2 = 7
比较元素:70
58 < 70 → 去左半段(5~6)
③ 第三次比较
low = 5, high = 6
mid = (5 + 6) / 2 = 5
比较元素:30
58 > 30 → 去右半段(6~6)
④ 第四次比较
low = 6, high = 6
mid = 6
比较元素:50
58 > 50 → 去右半段(7~6),查找失败。
🎯 最终比较序列
依次比较了:20 → 70 → 30 → 50
二、程序题

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
// --------- 二叉链表结构 ---------
typedef struct BTNode {
ElemType data;
struct BTNode *lchild, *rchild;
} BTNode, *BTree;
// --------- 构建二叉树:先序输入,0 表示空 ---------
int CreateBTree(BTree *T) {
int x;
if (scanf("%d", &x) != 1) return 0; // 输入失败
if (x == 0) {
*T = NULL;
return 1;
} else {
*T = (BTree)malloc(sizeof(BTNode));
if (*T == NULL) {
fprintf(stderr, "内存分配失败\n");
exit(1);
}
(*T)->data = x;
if (!CreateBTree(&((*T)->lchild))) return 0;
if (!CreateBTree(&((*T)->rchild))) return 0;
return 1;
}
}
// --------- 中序遍历(无全局变量,参数 first 控制空格) ---------
void InOrder(BTree T, int *first) {
if (T == NULL) return;
InOrder(T->lchild, first);
if (*first) {
printf("%d", T->data);
*first = 0;
} else {
printf(" %d", T->data);
}
InOrder(T->rchild, first);
}
// --------- 判断是否平衡二叉树(AVL) ---------
int IsBalanced(BTree T, int *height) {
if (T == NULL) {
*height = 0;
return 1;
}
int lh = 0, rh = 0;
int left_balanced = IsBalanced(T->lchild, &lh);
int right_balanced = IsBalanced(T->rchild, &rh);
*height = (lh > rh ? lh : rh) + 1;
if (!left_balanced || !right_balanced) return 0;
if (abs(lh - rh) > 1) return 0;
return 1;
}
// --------- 释放二叉树内存 ---------
void DestroyTree(BTree T) {
if (T == NULL) return;
DestroyTree(T->lchild);
DestroyTree(T->rchild);
free(T);
}
int main() {
BTree T = NULL;
if (!CreateBTree(&T)) {
fprintf(stderr, "二叉树构造失败\n");
return 1;
}
// 输出中序遍历
int first = 1;
InOrder(T, &first);
printf("\n");
// 判断是否平衡
int height;
int ok = IsBalanced(T, &height);
printf("%d\n", ok);
// 释放内存
DestroyTree(T);
return 0;
}
三、代码讲解
1️⃣ 头文件与类型定义
#include <stdio.h>
#include <stdlib.h>
-
stdio.h:提供scanf、printf等输入输出函数。 -
stdlib.h:提供malloc、free、exit等动态内存和程序控制函数。
typedef int ElemType;
-
ElemType:节点存储的数据类型。-
类型:
int -
用途:二叉树节点保存的数据。
-
设计意义:可灵活修改为其他类型,如
float、char。
-
typedef struct BTNode {
ElemType data; // 节点存储的值
struct BTNode *lchild; // 左子树指针
struct BTNode *rchild; // 右子树指针
} BTNode, *BTree;
-
BTNode:二叉树节点结构体。-
data:存储节点值 -
lchild:指向左子树 -
rchild:指向右子树
-
-
BTree:BTNode*类型,表示二叉树指针,便于函数传递。
2️⃣ 构建二叉树函数 CreateBTree
int CreateBTree(BTree *T) {
-
T:BTree*类型,指向二叉树节点指针。-
用途:函数内部修改节点地址可以回传到上一层递归。
-
int x;
-
x:存储当前节点的输入值。-
用途:暂存用户输入的数据,决定当前节点值或空节点。
-
if (scanf("%d", &x) != 1) return 0;
-
功能:从标准输入读取一个整数存入
x。 -
变量解释:
x保存输入值 -
设计意义:防止输入非法导致程序崩溃,返回 0 表示失败。
if (x == 0) {
*T = NULL;
return 1;
} else {
-
*T:当前节点指针 -
功能:输入为 0 表示空节点,直接置空并返回构造成功。
-
设计意义:递归终止条件。
*T = (BTree)malloc(sizeof(BTNode));
-
*T:分配节点的指针 -
功能:为当前节点动态申请内存。
if (*T == NULL) {
fprintf(stderr, "内存分配失败\n");
exit(1);
}
-
功能:检查
malloc是否成功,失败退出程序。 -
变量:
*T是分配的节点。
(*T)->data = x;
-
(*T)->data:节点存储的值 -
功能:将输入值赋给节点。
if (!CreateBTree(&((*T)->lchild))) return 0;
if (!CreateBTree(&((*T)->rchild))) return 0;
-
(*T)->lchild:左子树指针 -
(*T)->rchild:右子树指针 -
功能:递归创建左、右子树。
-
设计意义:二叉树递归构造,根→左→右。
return 1;
}
}
-
返回值:1 表示当前节点及子树构造成功。
3️⃣ 中序遍历函数 InOrder
void InOrder(BTree T, int *first) {
-
T:当前节点 -
first:整型指针,控制输出格式,首元素不加空格,后续加空格。
if (T == NULL) return;
-
功能:空节点直接返回,递归终止条件。
InOrder(T->lchild, first);
-
T->lchild:左子树指针 -
功能:递归遍历左子树(中序遍历顺序)。
if (*first) {
printf("%d", T->data);
*first = 0;
} else {
printf(" %d", T->data);
}
-
T->data:当前节点值 -
*first:控制输出空格 -
功能:格式化输出节点值。
-
设计意义:保证输出严格按照题目要求。
InOrder(T->rchild, first);
}
-
T->rchild:右子树指针 -
功能:递归遍历右子树,完成中序遍历。
4️⃣ 判断平衡二叉树:IsBalanced
int IsBalanced(BTree T, int *height) {
-
T:当前节点 -
height:返回当前节点的子树高度
if (T == NULL) {
*height = 0;
return 1;
}
-
变量说明:
-
空树高度为 0,视为平衡
-
-
用途:递归基准条件。
int lh = 0, rh = 0;
-
lh:左子树高度 -
rh:右子树高度
int left_balanced = IsBalanced(T->lchild, &lh);
int right_balanced = IsBalanced(T->rchild, &rh);
-
left_balanced:左子树是否平衡 -
right_balanced:右子树是否平衡 -
lh、rh:子树高度返回值 -
功能:递归判断子树平衡,同时获取高度。
*height = (lh > rh ? lh : rh) + 1;
-
*height:当前节点高度 -
用途:左、右子树高度最大值 + 1,供上一层使用。
if (!left_balanced || !right_balanced) return 0;
if (abs(lh - rh) > 1) return 0;
-
判断条件:
-
子树不平衡或高度差 > 1,则当前节点不平衡
-
-
返回值:0 表示不平衡,1 表示平衡
return 1;
}
-
当前节点平衡,返回 1
5️⃣ 释放二叉树:DestroyTree
void DestroyTree(BTree T) {
if (T == NULL) return;
-
T:当前节点指针 -
空节点直接返回,递归终止。
DestroyTree(T->lchild);
DestroyTree(T->rchild);
-
左、右子树递归释放内存。
free(T);
}
-
释放当前节点内存。
6️⃣ 主函数 main
int main() {
BTree T = NULL;
-
T:二叉树根节点指针,初始为空。
if (!CreateBTree(&T)) {
fprintf(stderr, "二叉树构造失败\n");
return 1;
}
-
构建二叉树,并检查成功
-
错误处理,防止程序异常。
int first = 1;
InOrder(T, &first);
printf("\n");
-
first:控制中序遍历输出格式 -
调用中序遍历并打印节点值
int height;
int ok = IsBalanced(T, &height);
printf("%d\n", ok);
-
height:二叉树高度 -
ok:是否平衡,1=平衡,0=不平衡
DestroyTree(T);
return 0;
}
-
释放二叉树内存,正常退出程序。

被折叠的 条评论
为什么被折叠?



