
第四课《长歪的大树------BST退化危机》
🌟故事开始:魔法图书馆出大事了!
1、经过前三课。
魔法图书馆已经越来越厉害了!
同学们已经学会:
BST搜索
BST插入
BST遍历
大家都觉得:
🌳"BST天下无敌!"
2、可是有一天......
图书管理员爷爷突然哭了:
😭"搜索变慢了!!!"
3、同学们很震惊:
😮"不可能呀!"
BST不是很快吗?
4、爷爷说:
📚"以前找书只要几秒。"
📚"现在找一本书要跑半个图书馆!"
5、到底发生了什么?
今天。
我们就来揭开:
⚔️BST最大的危机⚔️
🌳树退化(Degenerate)
第一部分:正常的BST长什么样?
1、先看一棵健康的BST:
8
/ \
3 10
/ \ \
1 6 14
2、🌟为什么它快?
因为:
每次比较。
都能:
🌟排除一大片!
3、例如找14:
8 → 10 → 14
只走3步!
4、🌟这棵树像什么?
像:
🌳一棵自然生长张开的大树
左右都比较均匀。
第二部分:危险的插入顺序
1、有一天。
来了几本新书:
1 2 3 4 5
注意!
它们是:
🌟按顺序来的!
2、图书管理员开始插入。
🌟插入1
1
🌟插入2
因为:
2 > 1
所以:
1
\
2
🌟插入3
3 > 1
3 > 2
继续右边。
结果:
1
\
2
\
3
🌟插入4
继续右边。
1
\
2
\
3
\
4
🌟插入5
最后:
1
\
2
\
3
\
4
\
5
3、😱大事不好了!
树长歪了!
第三部分:什么叫"退化"?
1、原来的BST:
8
/ \
3 10
像:
🌳真正的大树
2、现在的BST:
1
\
2
\
3
像:
🌵电线杆!
3、🌟这就叫:
🎯BST退化!
4、🌟退化是什么意思?
原本:
树
慢慢变成:
链表
5、🌟结果会怎样?
搜索速度大大变慢!
第四部分:为什么会变慢?
原来找5:
1、🌟正常BST
可能:
8 → 6 → 5
很快。
2、🌟退化后
必须:
1 → 2 → 3 → 4 → 5
一个一个走!
3、😱这不就和顺序查找一样了吗?
4、🌟BST的魔法消失了!
因为:
🌟无法"排除一大片"
第五部分:为什么会退化?
1、原因其实很简单:
🌟插入顺序太特殊!
2、例如:
1 2 3 4 5
每次都往右。
3、或者:
5 4 3 2 1
每次都往左。
4、树就会:
🌟越长越歪!
第六部分:平衡思想登场!
算法国王召开紧急会议!
1、算法科学家发现:
🌟真正重要的不只是BST
而是:
🌟"树要平衡!"
2、🌟什么叫平衡?
例如:
4
/ \
2 6
/ \ / \
1 3 5 7
左右高度差不多。
这就叫:
🌟平衡树
3、🌟为什么平衡很重要?
因为:
搜索时:
每次都能:
🌟快速缩小范围!
第七部分:生活中的例子
🌟例子1:图书馆书架
1、如果:
所有书全堆一排。
找书很慢。
2、但如果:
分成:
左边
中间
右边
会快很多!
🌟例子2:猜数字
1、如果每次都:
🌟猜中间
会很快。
2、如果每次都:
🌟只猜旁边
就会很慢。
3、🌟BST也是一样!
第八部分:算法世界的升级
后来。
算法科学家发明了:
1、🌟AVL树
会自动保持平衡。
2、🌟红黑树
更强大的平衡树。
3、很多生活中的程序:
地图导航
数据库
游戏系统
都在用!
第九部分:观察实验
现场演示。
🌟实验1:好树
插入:
4 2 6 1 3 5 7
形成:
4
/ \
2 6
很平衡。
🌟实验2:坏树
插入:
1 2 3 4 5 6 7
形成:
1
\
2
\
3
长歪。
🌟然后比较搜索次数!
第十部分:程序演示
1、🌟构建退化BST
#include <iostream>
using namespace std;
struct Node
{
int val;
Node* left;
Node* right;
Node(int x)
{
val = x;
left = NULL;
right = NULL;
}
};
Node* insert(Node* root, int x)
{
if(root == NULL)
{
return new Node(x);
}
if(x < root->val)
{
root->left = insert(root->left, x);
}
else if(x > root->val)
{
root->right = insert(root->right, x);
}
return root;
}
// 中序遍历
void inorder(Node* root)
{
if(root == NULL)
{
return;
}
inorder(root->left);
cout << root->val << " ";
inorder(root->right);
}
int main()
{
Node* root = NULL;
// 按顺序插入
for(int i = 1; i <= 7; i++)
{
root = insert(root, i);
}
cout << "中序遍历:" << endl;
inorder(root);
return 0;
}
2、🌟程序虽然没错
输出:
1 2 3 4 5 6 7
3、但树已经:
😱严重退化!
第十一部分:课堂互动小游戏
🌟游戏1:谁是健康树?
老师画两棵树。
让孩子判断:
-
哪棵平衡
-
哪棵退化
🌟游戏2:真人长树
孩子们按顺序站队:
1 2 3 4 5
会形成"电线杆"。
再换顺序:
4 2 6 1 3 5 7
会形成平衡树。
孩子会特别直观!
第十二部分:今天重要的思想
🌟BST算法也会"变笨"!
BST:
不是永远都快。
🌟数据的排列方式
会影响效率!
这是需要理解的算法思想。
第十三部分:本课总结
🌟今天学会了什么?
1、🌳BST可能退化
变成:
🌵"电线杆"
2、🌳为什么会退化?
插入顺序太特殊。
3、🌳退化后会怎样?
搜索变慢。
4、🌳重要思想
🌟树要平衡!
5、🌟记住一句重要的话
🌳算法不是永远无敌。
🌳好的结构,才能有好的效率。