AVL树模板
///AVL树模板
typedef struct Node ///树的节点
{
int val,data;
int h; ///以当前结点为根结点的数的高度
int bf; ///平衡因子(左子树高度与右子树高度之差)
Node *left,*right;
}Node; class AvlTree ///alv树,树中太多函数,用类来实现容易一些
{
private:
Node *root; ///树的根节点
public:
void Init() ///初始化树
{
root=NULL;
}
int Height(Node *T) ///取一个节点的高度
{
if (T==NULL) return ;
return T->h;
}
int Bf(Node *T) ///计算一个节点的平衡因子
{
if (T->left==T->right) return ;
if (T->left==NULL) return -(T->right->h); ///这里一定取负数(左子树高度与右子树高度之差)
if (T->right==NULL) return T->left->h;
return (T->left->h)-(T->right->h);
}
///四种旋转,不知为什么,自己多画一下就知道了。
Node *LL_rotate(Node *T) ///单向右旋平衡处理LL:由于在*T的左子树根结点的左子树上插入结点
{
Node *B=T->left;
T->left=B->right;
B->right=T;
T->h=max(Height(T->left),Height(T->right))+;
B->h=max(Height(B->left),Height(T->right))+;
T->bf=Bf(T);
B->bf=Bf(B);
return B;
}
Node *RR_rotate(Node *T) ///单向左旋平衡处理RR:由于在*T的右子树根结点的右子树上插入结点
{
Node *B=T->right;
T->right=B->left;
B->left=T;
T->h=max(Height(T->left),Height(T->right))+;
B->h=max(Height(B->left),Height(T->right))+;
T->bf=Bf(T);
B->bf=Bf(B);
return B;
}
Node *LR_rotate(Node *T) ///双向旋转平衡处理LR:由于在*T的左子树根结点的右子树上插入结点
{
T->left=RR_rotate(T->left);
T=LL_rotate(T);
return T;
}
Node *RL_rotate(Node *T) ///双向旋转平衡处理RL:由于在*T的右子树根结点的左子树上插入结点
{
T->right=LL_rotate(T->right);
T=RR_rotate(T);
return T;
}
void Insert(int v,int e) ///root是private,所以不能从主函数传入
{
Insert(root,v,e);
}
void Insert(Node *&T,int v,int e) ///插入新节点
{
if (T==NULL)
{
T=(Node *)malloc(sizeof(Node));
T->h=;
T->bf=;
T->val=v;
T->data=e;
T->left=T->right=NULL;
return ;
}
if (e<T->data) Insert(T->left,v,e);
else Insert(T->right,v,e);
T->h=max(Height(T->left),Height(T->right))+; ///计算节点高度
T->bf=Bf(T); ///计算平衡因子
if (T->bf>||T->bf<-) ///调整平衡,四种调整反法
{
if (T->bf>&&T->left->bf>) T=LL_rotate(T); ///如果T->bf > 1 则肯定有左儿子
if (T->bf<-&&T->right->bf<) T=RR_rotate(T); ///如果T->bf < -1 则肯定有右儿子
if (T->bf>1&&T->left->bf<0) T=LR_rotate(T);
if (T->bf<-1&&T->right>0) T=RL_rotate(T);
}
}
void Find(int flag) ///flag=1为找最大值,否则找最小值
{
if (root==NULL)
{
printf("0\n");
return ;
}
Node *temp=root;
if (flag) ///最大值一定最右边
{
while (temp->right)
temp=temp->right;
}
else
{
while (temp->left)
temp=temp->left;
}
printf("%d\n",temp->val);
Delete(root,temp->data); ///删除相应节点
}
void Delete(Node *&T,int e)
{
if (T==NULL) return ;
if (e<T->data) Delete(T->left,e);
else if (e>T->data) Delete(T->right,e);
else ///找到删除的节点
{
if (T->left&&T->right) ///删除的节点左右都还有节点
{
Node *temp=T->left; ///把左子树的最大值当做当前节点
while (temp->right) temp=temp->right; ///找最大值
T->val=temp->val;
T->data=temp->data;
Delete(T->left,temp->data); ///左子树最大值已近改为当前根节点,应该删除原来位置
}
else
{
Node *temp=T;
if (T->left) T=T->left; ///删除节点只存在左子树
else if (T->right) T=T->right; ///删除节点只有右子树
else ///删除节点没有孩子
{
free(T);
T=NULL;
}
if (T) free(temp);
return ;
}
}
T->h=max(Height(T->left),Height(T->right))+;
T->bf=Bf(T);
if (T->bf>||T->bf<-) ///删除后一定要调整
{
if (T->bf>&&T->left->bf>) T=LL_rotate(T);
if (T->bf<-&&T->right->bf<) T=RR_rotate(T);
if (T->bf>&&T->left->bf<) T=LR_rotate(T);
if (T->bf<-&&T->right>) T=RL_rotate(T);
}
}
void Free() ///由于内存是malloc出来的,最后一定要释放
{
FreeNode(root);
}
void FreeNode(Node *T)
{
if (T==NULL) return ;
if (T->right) FreeNode(T->right);
if (T->left) FreeNode(T->left);
free(T);
}
};
AVL树模板的更多相关文章
- PAT甲级题解-1066. Root of AVL Tree (25)-AVL树模板题
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6803291.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- 数据结构图文解析之:AVL树详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- C++模板实现的AVL树
1 AVL树的定义 AVL树是一种自平衡二叉排序树.它的特点是不论什么一个节点的左子树高度和右子树的高度差在-1,0,1三者之间. AVL树的不论什么一个子树都是AVL树. 2 AVL树的实现 AVL ...
- 【PAT甲级】1066 Root of AVL Tree (25 分)(AVL树建树模板)
题意: 输入一个正整数N(<=20),接着输入N个结点的值,依次插入一颗AVL树,输出最终根结点的值. AAAAAccepted code: #define HAVE_STRUCT_TIMESP ...
- PAT甲级1123 Is It a Complete AVL Tree【AVL树】
题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805351302414336 题意: 给定n个树,依次插入一棵AVL ...
- 二叉查找树,AVL树,伸展树【CH4601普通平衡树】
最近数据结构刚好看到了伸展树,在想这个东西有什么应用,于是顺便学习一下. 二叉查找树(BST),对于树上的任意一个节点,节点的左子树上的关键字都小于这个节点的关键字,节点的右子树上的关键字都大于这个节 ...
- PAT甲级题解-1123. Is It a Complete AVL Tree (30)-AVL树+满二叉树
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6806292.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- AVL树原理及实现(C语言实现以及Java语言实现)
欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. AVL定义 AVL树是一种改进版的搜索二叉树.对于一般的搜索二叉树而言,如果数据恰好 ...
随机推荐
- Android无法收到指定广播的问题总结
首先是应用中不能只有一个广播,必须有一个activity或者service(这种情况比较复杂参考http://www.cnblogs.com/welcoming/p/4120497.html) 简单的 ...
- Windows下使用scapy+python2.7实现对pcap文件的读写操作
scapy在linux环境中对pcap文件进行操作非常方便,但在windows下,特别是在python2.7环境下却会碰到各种各样的依赖包无法使用的问题,最明显的可能就属dnet和pcap的pytho ...
- centos中rabbitmq的安装及php支持
转自:http://www.phpac.com/741.html 1.安装rabbitmq-c库和codegen配件 wget https://github.com/alanxz/rabbitmq-c ...
- JS运动从入门到精髓!哈哈
首先来看最基础的运动:单个物体向右匀速运动到某一点停止 例子:一个按钮,一个div,点击按钮,让div向右运动到某一个位置暂停 // 原理: 1 获取物体当前的位置 oDiv.offsetl ...
- (转)JPEG图片数据结构分析- 附Png数据格式详解.doc
一.简述 JPEG是一个压缩标准,又可分为标准JPEG.渐进式JPEG及JPEG2000三种: ①标准JPEG:以24位颜色存储单个光栅图像,是与平台无关的格式,支持最高级别的压缩,不过,这种压 ...
- Oracle游标示例
-- 声明游标:CURSOR cursor_name IS select_statement --For 循环游标 --(1)定义游标 --(2)定义游标变量 --(3)使用for循环来使用这个游标 ...
- sp_help 快速查看表结构、视图信息
sp_helptext: 是MS SQL Server的一个系统存储过程,可以通过它来查看存储过程或者视图.函数源码 示例:sp_helptext viewName (viewName 即要查询的存 ...
- (String)151. Reverse Words in a String
Given an input string, reverse the string word by word. For example,Given s = "the sky is blue& ...
- 清理Oracle安装目录里的一些日志信息
最近测试环境服务器上磁盘空间紧张,表空间里面的数据也不知道开发哪些需要哪些不需要,而且因为此测试库运行时间比较久远,起码有三年了.于是就从清理Oracle安装目录下的日志下手. 发现在一般这几个日志, ...
- javascript URI的编码
用encodeURIComponent,但是不清楚她和encodeURI的区别, w3school 对其的解释: encodeURIComponent() 函数可把字符串作为 URI 组件进行编码.( ...