平衡二叉树的插入过程: http://www.cnblogs.com/hujunzheng/p/4665451.html

对于二叉平衡树的删除采用的是二叉排序树删除的思路:

  假设被删结点是*p,其双亲是*f,不失一般性,设*p是*f的左孩子,下面分三种情况讨论:
  ⑴ 若结点*p是叶子结点,则只需修改其双亲结点*f的指针即可。
  ⑵ 若结点*p只有左子树PL或者只有右子树PR,则只要使PL或PR 成为其双亲结点的左子树即可。
  ⑶ 若结点*p的左、右子树均非空,先找到*p的中序前趋结点*s(注意*s是*p的左子树中的最右下的结点,它的右链域为空),然后有两种做法:
    ① 令*p的左子树直接链到*p的双亲结点*f的左链上,而*p的右子树链到*p的中序前趋结点*s的右链上。
    ② 以*p的中序前趋结点*s代替*p(即把*s的数据复制到*p中),将*s的左子树链到*s的双亲结点*q的左(或右)链上。

注:leftBalance_del 和 rightBalance_del方法是在删除节点时对左子树和右子树的平衡调整,leftBalance 和 rightBalance方法是在插入节点是对左右子树的平衡调整。 在具体调整的时候,和插入式调整时运用同样的分类方法,这里介绍一种情况,如下图所示(代码部分见代码中的提示)

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<cstdio>
#define LH 1 //左高
#define EH 0 //等高
#define RH -1 //右高
using namespace std;template <typename ElemType>
class BSTNode{public:ElemType data;//节点的数据 int bf;//节点的平衡因子BSTNode *child[2];BSTNode(){child[0] = NULL;child[1] = NULL;}
};typedef BSTNode<string> BSTnode, *BSTree;template <typename ElemType>
class AVL{public:BSTNode<ElemType> *T;void buildT();void outT(BSTNode<ElemType> *T);void deleteAVL(BSTNode<ElemType>* &T, ElemType key, bool &shorter);bool insertAVL(BSTNode<ElemType>* &T, ElemType key, bool &taller); private:void deleteNode(BSTNode<ElemType>* T, BSTNode<ElemType>* &s, BSTNode<ElemType>* p, bool flag, bool &shorter);void rotateT(BSTNode<ElemType>* &o, int x);//子树的左旋或者右旋void leftBalance(BSTNode<ElemType>* &o);void rightBalance(BSTNode<ElemType>* &o);void leftBalance_del(BSTNode<ElemType>* &o);void rightBalance_del(BSTNode<ElemType>* &o);
};template <typename ElemType>
void AVL<ElemType>::rotateT(BSTNode<ElemType>* &o, int x){BSTNode<ElemType>* k = o->child[x^1];o->child[x^1] = k->child[x];k->child[x] = o;o = k;
}template <typename ElemType>
void AVL<ElemType>::outT(BSTNode<ElemType> *T){if(!T) return;cout<<T->data<<" ";outT(T->child[0]);outT(T->child[1]);
}template <typename ElemType>
void AVL<ElemType>::buildT(){T = NULL;ElemType key;while(cin>>key){if(key==0) break;bool taller = false;insertAVL(T, key, taller);}
}template <typename ElemType>
void AVL<ElemType>::deleteNode(BSTNode<ElemType>* T, BSTNode<ElemType>* &s, BSTNode<ElemType>* p, bool flag, bool &shorter){if(flag){flag = false;deleteNode(T, s->child[0], s, flag, shorter);if(shorter){switch(s->bf){case LH:s->bf = EH;shorter = false;break; case EH:s->bf = RH;shorter = true;break; case RH:rightBalance_del(s);shorter = false;break;}}} else {if(s->child[1]==NULL){T->data = s->data;BSTNode<ElemType>* ss = s; if(p != T){p->child[1] = s->child[0];} else {p->child[0] = s->child[0];}delete ss;//s是引用类型,不能delete s shorter = true; return ;}deleteNode(T, s->child[1], s, flag, shorter);if(shorter){switch(s->bf){case LH://这是上面配图的情况leftBalance_del(s);shorter = false; break; case EH:s->bf = LH;shorter = true;break; case RH:s->bf = EH;shorter = false;break;}} }
} template <typename ElemType>
bool AVL<ElemType>::insertAVL(BSTNode<ElemType>* &T, ElemType key, bool &taller){if(!T){//插入新的节点,taller=true 那么树的高度增加 T = new BSTNode<ElemType>();T->data = key;T->bf = EH;taller = true;} else {if(T->data == key){taller = false;return false;}if(T->data > key){//向T的左子树进行搜索并插入 if(!insertAVL(T->child[0], key, taller)) return false;if(taller){//
                switch(T->bf){case LH://此时左子树的高度高,左子树上又插入了一个节点,失衡,需要进行调整
                        leftBalance(T);taller = false;//调整之后高度平衡 break; case EH:T->bf = LH;taller = true;break; case RH:T->bf = EH;taller = false;                        break;}}} if(T->data < key) {//向T的右子树进行搜索并插入 if(!insertAVL(T->child[1], key, taller)) return false;switch(T->bf){case LH:T->bf = EH;taller = false; break; case EH:T->bf = RH;taller = true;break; case RH:rightBalance(T);    taller = false;                    break;}}}return true;
}template <typename ElemType>
void AVL<ElemType>::deleteAVL(BSTNode<ElemType>* &T, ElemType key, bool &shorter){if(T->data == key){BSTNode<ElemType>*q, s; if(!T->child[1]){//右子树为空,然后重接其左子树 q = T;T = T->child[0];shorter = true;//树变矮了 delete q;} else if(!T->child[0]){//左子树为空,重接其右子树 q = T;T = T->child[1];shorter = true;//树变矮了 delete q;} else {//左右子树都非空 ,也就是第三种情况 deleteNode(T, T, NULL, true, shorter);shorter = true;} } else if(T->data > key) {//左子树 deleteAVL(T->child[0], key, shorter);if(shorter){switch(T->bf){case LH:T->bf = EH; shorter = false;break;case RH:rightBalance_del(T);shorter = false;break;case EH:T->bf = RH;shorter = true;break;}}} else if(T->data < key){//右子树 deleteAVL(T->child[1], key, shorter);if(shorter){switch(T->bf){case LH://这是上面配图的情况leftBalance_del(T);shorter = false;                    break;case RH:T->bf = EH;shorter = false; break;case EH:T->bf = LH;shorter = true;break;}}}
}template <typename ElemType>
void AVL<ElemType>::leftBalance(BSTNode<ElemType>* &T){BSTNode<ElemType>* lchild = T->child[0];switch(lchild->bf){//检查T的左子树的平衡度,并作相应的平衡处理 case LH://新节点 插入到 T的左孩子的左子树上,需要对T节点做单旋(右旋)处理 T->bf = lchild->bf = EH; rotateT(T, 1);break;case RH://新节点 插入到 T的左孩子的右子树上,需要做双旋处理  1.对lchild节点进行左旋,2.对T节点进行右旋 BSTNode<ElemType>* rdchild = lchild->child[1];switch(rdchild->bf){//修改 T 及其左孩子的平衡因子 case LH: T->bf = RH; lchild->bf = EH; break;case EH: T->bf = lchild->bf = EH; break;//发生这种情况只能是 rdchild无孩子节点case RH: T->bf = EH; lchild->bf = LH; break; }rdchild->bf = EH; rotateT(T->child[0], 0);//不要写成 rotateT(lc, 0);//这样的话T->lchild不会改变 rotateT(T, 1);break;}
}template <typename ElemType>
void AVL<ElemType>::rightBalance(BSTNode<ElemType>* &T){BSTNode<ElemType>* rchild = T->child[1];switch(rchild->bf){//检查T的左子树的平衡度,并作相应的平衡处理 case RH://新节点 插入到 T的右孩子的右子树上,需要对T节点做单旋(左旋)处理 T->bf = rchild->bf = EH; rotateT(T, 0);break;case LH://新节点 插入到 T的右孩子的左子树上,需要做双旋处理  1.对rchild节点进行右旋,2.对T节点进行左旋 BSTNode<ElemType>* ldchild = rchild->child[0];switch(ldchild->bf){//修改 T 及其右孩子的平衡因子 case LH: T->bf = EH; rchild->bf = RH; break;case EH: T->bf = rchild->bf = EH; break;//发生这种情况只能是 ldchild无孩子节点 case RH: T->bf = LH; rchild->bf = EH; break; }ldchild->bf = EH; rotateT(T->child[1], 1);rotateT(T, 0);break;}
}template <typename ElemType>
void AVL<ElemType>::leftBalance_del(BSTNode<ElemType>* &T){BSTNode<ElemType>* lchild = T->child[0];switch(lchild->bf){ case LH:T->bf = EH; lchild->bf = EH; rotateT(T, 1);break;case EH:T->bf = LH;lchild->bf = EH; rotateT(T, 1);break;case RH://这是上面配图的情况BSTNode<ElemType>* rdchild = lchild->child[1];switch(rdchild->bf){ case LH:T->bf = RH;lchild->bf = rdchild->bf = EH;break;case EH:rdchild->bf = T->bf = lchild->bf = EH; break;case RH:T->bf = rdchild->bf = EH;lchild->bf = LH; break;}rotateT(T->child[0], 0);rotateT(T, 1);break;}
}template <typename ElemType>
void AVL<ElemType>::rightBalance_del(BSTNode<ElemType>* &T){BSTNode<ElemType>* rchild = T->child[1];BSTNode<ElemType>* ldchild = rchild->child[0];switch(rchild->bf){ case LH:switch(ldchild->bf){ case LH:ldchild->bf = T->bf = EH; rchild->bf = RH;break;case EH:ldchild->bf = T->bf = rchild->bf = EH; break;case RH:rchild->bf = T->bf = EH; ldchild->bf = LH;break;}rotateT(T->child[1], 1);rotateT(T, 0);break;case EH://outT(this->T);e EH:T->bf = RH;rchild->bf = EH; rotateT(T, 0);break;case RH:T->bf = EH; rchild->bf = EH; rotateT(T, 0);break;}
}int main(){AVL<int> avl;avl.buildT();cout<<"平衡二叉树先序遍历如下:"<<endl;avl.outT(avl.T);cout<<endl;bool shorter = false;avl.deleteAVL(avl.T, 24, shorter);avl.outT(avl.T);return 0;
} /*13 24 37 90 53 013 24 37 90 53 12 26 0
*/

转载于:https://www.cnblogs.com/hujunzheng/p/4669058.html

平衡二叉树AVL删除相关推荐

  1. 一种基于平衡二叉树(AVL树)插入、查找和删除的简易图书管理系统

    目录 1. 需求分析 2. 项目核心设计 2.1 结点插入 2.2 结点删除 3 测试结果 4 总结分析 4.1 调试过程中的问题是如何解决的,以及对设计与实现的回顾讨论和分析 4.2 算法的时间和空 ...

  2. avl删除根节点图解_图解 6 种树,你心中有数吗。。。

    数据结构这门课程是计算机相关专业的基础课,数据结构指的是数据在计算机中的存储.组织方式. 我们在学习数据结构时候,会遇到各种各样的基础数据结构,比如堆栈.队列.数组.链表.树...这些基本的数据结构类 ...

  3. [转]C#与数据结构--树论--平衡二叉树(AVL Tree)

    C#与数据结构--树论--平衡二叉树(AVL Tree) http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html 介绍 我们知道在二 ...

  4. 平衡二叉树AVL详解

    一.平衡二叉树的定义 平衡二叉树(Balanced Binary Tree)又被称为AVL树,它且具有以下性质: (1)它是一棵空树或它的左右两个子树的高度差的绝对值不超过1: (2)并且左右两个子树 ...

  5. 平衡二叉树平衡因子怎么计算_数据结构PHP 平衡二叉树(AVL)的平衡原理

    这篇文章主要介绍一下 平衡二叉树(AVL),对于 二分搜索树 来说,如果树上的 元素 是顺序 添加的,会导致数据退化成一个 链表,这样就会造成很严重的性能问题,此时就需要在 二分搜索树 的基础上,保证 ...

  6. [ 数据结构 ] 平衡二叉树(AVL)--------左旋、右旋、双旋

    0 引出 数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在 回顾:二叉搜索树 左子树全部为空,从形式上看,更像一个单链表. 插入速度没有影响 查询速度明显降低(因为需 ...

  7. Python数据结构11:树的实现,树的应用,前中后序遍历,二叉查找树BST,平衡二叉树AVL树,哈夫曼树和哈夫曼编码

    1.概念 树一种基本的"非线性"数据结构. 相关术语: 节点Node:组成树的基本部分.每个节点具有名称,或"键值",节点还可以保存额外数据项,数据项根据不同的 ...

  8. java数据结构与算法之平衡二叉树(AVL树)的设计与实现中的事实代码

    普通二叉查找树的问题   在开篇,我们提到过,普通二叉树(二叉查找树)在操作的时间复杂度上不一定遵循O(㏒n),也有可能是O(n),这是为什么呢?在上一篇中,我们明明插入都按照一定规则比较的呀,其实那 ...

  9. Java数据结构——平衡二叉树(AVL树)

    AVL树的引入 搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以下极端情况: 这样的二叉树搜索效率甚至比链表还低.在搜索二叉树基础上出现的平衡二叉树(AVL树)就解决了这样的问题.当平衡二叉树(A ...

最新文章

  1. invoke 数组_对于反射中的invoke()方法的理解
  2. vue.jsr入门_JSR 365更新:深入CDI 2.0
  3. NVIDIA DGX低至7.5折限时抢购,全球首款深度学习超级计算机组合
  4. 和商简智能CEO关于APS的聊后感
  5. Sipdroid项目的编译运行
  6. python实现音乐播放器_【原创源码】用Python来实现一个简易的MP3播放器(采用酷我接口,包含接口分析)...
  7. java jsonobject 清空_有没有办法,我可以清空整个JSONObject – java
  8. 美赛O奖、F奖论文写作技巧!【微信公众号:校园数模】
  9. 蓝桥杯-奇妙的数字(2015-A-3)
  10. Qt视频直播软件--项目实战(Day1)
  11. Python截屏工具,识别屏幕中的二维码
  12. NHibernate Step by Step (三) Configuration和Sessionfactory
  13. 【读书笔记】曾国藩的正面与侧面(二)
  14. 高工指数首发,德赛西威/哈曼/比亚迪「领衔」智能车机TOP10
  15. 静态创意和动态创意_8种独特且价格合理的名片的创意
  16. ldrex strex
  17. 昨天介入600571,信雅达,喜欢的朋友可以跟进!
  18. python语言用法_python语言基本语句用法总结
  19. 和石侃博士关于“香山”的一小时讨论
  20. UCK全球路演走进佛山,跨链技术将加速区块链商业应用

热门文章

  1. python里元组和列表的共同点和不同点_Python_列表,元组和字典的异同
  2. java怎么配置哨兵模式_redis 哨兵模式配置与spring集成
  3. Apache JMeter 下载
  4. Spring中,使用工具类无法自动注入service
  5. Redis 工具类_慕课版本
  6. php的添加语句怎么写,php修改语句怎么写
  7. C语言 数组长度计算 - C语言零基础入门教程
  8. java欧洲_java欧洲/明斯克时区问题
  9. php是走什么协议,TCP是什么协议
  10. 酒店管理与计算机技术结合,(定稿)某酒店内部管理系统的开发与应用(完整版)...