当前位置:文档之家› 数据结构 AVL树

数据结构 AVL树


作业:
(HW8)
简答题: 2,3,4
程序题: 2,3,9
2.在二叉查找树类中增加三个成员函数:删除小于某个指定值的所有元素, 删除大于某个指定值得所有元素,删除某一指定范围中的所有元素。
3.将二叉查找树类中的插入、删除和查找函数改成非递归函数。
9.在二叉查找树中增加一个成员函数,找出集合中第k大的元素。
void menu(){
printf(" =================== Menu ================\n");
printf(" c -- clear
\n");
printf(" f -- find
\n");
printf(" i -- insert
\n");
printf(" d -- delete
ptr->
1
—— R 旋转 0
0 3
1
2
Hale Waihona Puke 1023
pptr->
[例1]
3 1
12
23
25
15
30
10
20
5
15
10 5
25
20
30
LR 型: case a)
—— L-R 旋转 1
0 4
1
2
3
4 3
2 1
0
0
-1
2
3
1
4
[例2]
k k1
k2
case b)
—— L-R 旋转
4
1
2
3
2
3
1
4
4
3
1
2
0、1、2、4、7、12、20、33、54、88 ……
而:Fibonacci 数列为: 0、1、1、2、3、 5、 8、13、21、34、55、89……
所以: N h = f(h+2) - 1 (可以用归纳法证明) ==> 转化为求 Fibonacci 数的问题。
现有:
==> 所以:n个结点的平衡树的树高最多为
i=1
|-------------------> |
|
< i > n ? >---------------->(return)
| | | | | | | | | | | |
|N
A
< 以结点pi为根的子树Ti平衡? >------- |
|N
| |
以结点pi为根的子树进行调整(同插入调整) |
| <----------------- |
|y
|
以结点 k 为根的子树进行调整 (LL/LR/RL/RR)
| | |
| <----------------- | |
调整相关结点的平衡度
| (return)
Delete_AVL(AVLNODE* root, char info)
基本思想: 从局部到全局,逐步平衡调整
sub_tree
sub_tree
tree 2
parent left
tree 1
ptr
tree 2
tree 3
插入调整算法:
() |
按分类树的插入算法将结点 U 插入
并记根到 U 结点路径上的结点 p1,p2,p3......pm |
在结点 p1,p2,p3......pm 中确定调整结点 k
|
< 找到 k >----------------- |
8 9 10
9
8
10
平衡调整算法的实现: L - 旋转
||
|| ||
rotate_left( )
parent
parent
ptr
==>
right
tree 1
right
ptr
tree 3
tree 2
tree 3
tree 1
tree 2
R - 旋转 parent
left
ptr
==>
tree 3
tree 1
class BT_avl: public BT_sort{ public:
void insert_AVL(char info); bool delete_AVL(char info); void rotate_left(); void rotate_right(); void avl_balance(); void view_avl_balance(); private: int h(BNODE* root); };
printf("Please enter your choice:");
}
发生删除! 调整前后 高度发生变化?
==> shorter
[例题] 删除20
==> 高度改变 !
删除前
删除后
==> 继续调整
调整前
RR ==>
高度改变 !
调整后
==> 继续调整
==> RL 调整
==>
删除调整算法:
()
| 按分类树的删除算法找到最后被删结点D,删除D。
|
记D到根结点路径上的结点为 p1,p2,p3......pn |
class BT_sort: public BinaryTree{ public:
bool find_BST(char info); void insert_BST(char info); bool delete_BST(char info); };
---- 结点的平衡因子:{-1,0,1}
0
0
-1
2. 平衡二叉树 (AVL树)
平衡二叉树结点的定义: class BNODE{
char info; int avl_bal; BNODE* llink; BNODE* rlink; BNODE* parent; BNODE(){llink=0; rlink=0; parent=0;} };
结点的平衡因子(balance factor) —— height_left - height_right
\n");
printf(" A -- del_less_than
\n");
printf(" B -- del_large_than
\n");
printf(" C -- del_between
\n");
printf(" k -- kth
\n");
printf(" q -- quit
\n");
printf(" =================== End =================\n");
[例3]
k k1
k2
case c)
—— L-R 旋转
[例4] 插入I,H,G,F,E,D,C,B,A, 构造平衡树
() |
|————< 完成?>————>
|
|n
| |
插入一个结点
|
|
| |
调整
|—————— |
(end)
[例5] 插入以下结点,构造平衡二叉树: 8,9,10,2,1,5,3,6,4,7,11,12 (课堂练习)
printf("Please enter your choice:");
}
class BT_sort: public BinaryTree{ public:
bool find_BST(char info); void insert_BST(char info); bool delete_BST(char info); };
[例1] 插入 30
root
基本思想: —— 逐个插入,逐个调整 —— 先按分类树插入,再调整 —— 对局部调整,求全局平衡
关键:找到调整点k
调整点k的特点:
>> 原平衡因子非零 >> 根到插入结点路径上的结点 >> 最靠近插入结点
插入调整算法:
() |
按分类树的插入算法将结点U插入
记根到U结点路径上的结点为集合P |
project 2: AVL_tree —— 实现 BT_avl 类 —— 实现用户界面中的所有菜单项
void menu(){
printf(" =================== Menu ================\n");
printf(" c -- clear
\n");
printf(" f -- find
从集合P中找关键点k |
< 找到结点k >----------> |Y
| |
< 结点k平衡 >----------> |N
| |
调整集合P中相关结点的平衡度
按不同的调整类型进行调整
|
并调整相关结点的平衡度
|
| |
<---------------
| |
(return)
局部调整各种类型:
LL 型:(LL:表示新插入结点在危机结点k的左子树的左子树上)
class BT_avl: public BT_sort{ public:
void insert_AVL(char info); bool delete_AVL(char info); void rotate_left(); void rotate_right(); void avl_balance(); void view_avl_balance(); };
相关主题