第四章 树(2)
2013-05-24 21:10
169 查看
AVL树
一棵AVL树是每个节点的左子树和右子树的高度最多相差1的二叉查找树(空树的高度定义为-1)。插入一个节点可能会破坏AVL树的平衡性。如果发生这种情况就需要把平衡性质恢复了之后才认为插入这步完成。
在插入之后,只有那些从插入点到根节点的路径上的节点的平衡可能会被改变,因为只有这些节点的子树可能会发生变化。当我们沿着这条路径上行到根并更新平衡信息时,我们可以找到一个节点,它的新平衡破坏了AVL条件。
重新平衡AVL树的方法根据插入位置的不同分为单旋转和双旋转。插入发生在外边(左-左或者右-右)时使用单旋转,插入发生在内部(左-右或者右-左)时使用双旋转。
现在分别给出单旋转和双旋转的图和实现代码。根据图来实现代码非常简单。
单旋转:
Position SingleRotateWithLeft(Position k2) { Position k1; k1 = k2->Left; k2->Left = k1->Right; k2->Height = max(GetHeight(k2->Left), GetHeight(k2->Right)) + 1; k1->Height = max(GetHeight(k1->Left), k2->Height) + 1; return k1;//new root }
双旋转
Position DoubleRotateWithLeft(Position k3) { k3->Left = SingleRotateWithRight(k3->Left); return SingleRotateWithLeft(k3); } Position DoubleRotateWithRight(Position k3) { k3->Right = SingleRotateWithLeft(k3->Right); return SingleRotateWithRight(k3); }
AVL树的插入操作:
AVLTree Insert(ElementType X, AVLTree T) { if (T==NULL) { T = new struct AVLNode; if (T==NULL) { cout<<"out of space"<<endl; return NULL; } else { T->Element = X; T->Left = T->Right = NULL; T->Height = 0; } } else if (T->Element>X) { T->Left = Insert(X, T->Left); if (GetHeight(T->Left)-GetHeight(T->Right)==2) { if (X<T->Left->Element) T = SingleRotateWithLeft(T); else T = DoubleRotateWithLeft(T); } } else if (T->Element>X) { T->Right = Insert(X, T->Right); if (GetHeight(T->Right)-GetHeight(T->Left)==2) { if (X>T->Right->Element) T = SingleRotateWithRight(T); else T = DoubleRotateWithRight(T); } } T->Height = max(GetHeight(T->Left), GetHeight(T->Right)) + 1; return T; }
AVL树的删除可以使用懒惰删除。
伸展树
它保证从空树开始任意连续M次对树的操作最多花费O(MlogN)时间。虽然这种保证并不排除任意一次操作花费O(N)时间的可能。一棵伸展树每次操作的摊还代价是O(logN)。
伸展树的展开操作:
令X是在访问路径上的一个(非根)节点,我们将在这个路径上实施旋转操作。
1. 如果X的父节点是树根,我们只要旋转X和树根。否则X就存在父亲P和祖父G。
2. G-P-X呈之字形,则对G执行双旋转。
3. G-P-X呈一字型,则逆转树。
递归展开工作,直到X变成树根。
展开工作不仅将访问的节点移动到根处,而且还会把访问路径上的大部分节点的深度大致减少一半(某些浅的节点最多向下推后两个层次)。
可以通过访问要被删除的节点来实现删除工作。这种操作将节点上推到根处。如果删除该节点,则得到两棵子树TL和TR。如果我们找到TL中最大元素,那么这个元素就被旋转到TL的根下,而此时TL将有一个没有右儿子的根。可以使TR成为右儿子从而结束删除。
树的遍历
层序遍历与其他类型的遍历不同的地方在于它不是递归的实施的,它用到队列而不适用递归默认的栈。相关文章推荐
- [数据结构]第四章--串(读书笔记2)
- 算法竞赛入门经典第四章例题4-6 A Typical Homework (a.k.a Shi Xiong Bang Bang Mang) UVA - 12412
- Effective C++学习笔记之第四章(2)
- 第四章:继承
- 计算机网络(谢)——第四章读书笔记4.2
- AJ故事-第四章Beliefs
- 《TCP/IP协议详解》ARP与RARP(第四章与第五章)
- 第四章 Controller接口控制器详解(4)
- 第四章:存储过程
- 《Linux内核完全剖析-基于0.12内核》第四章的简单多任务内核Makefile的注释
- 算法竞赛入门经典训练指南第四章几何专题答案
- 第四章 视频编码基础
- 第四章:基于九鼎X210开发板移植2014.10版U-boot之使用sd卡启动
- 第四章:权限测试
- c和指针第四章编程练习代码
- 第四章--递归式
- 编程珠玑--------第四章习题笔记
- 第四章 例4.7
- 算法竞赛入门经典第四章