一步一步编写AVL树
第一步:定义结构体
typedef struct Node{
int d; //data
int h=; //height
struct Node* l=NULL;
struct Node* r=NULL;
Node(int d=):d(d){
}
}Node;
这个结构体和常规的二叉树结构体很相似。但是不同的是多了个属性“h”(height)。用这个属性来记录结点的高度,叶子结点为1,空结点为0 。
第二部:编写BST树的插入函数
Node* insert(Node* p,int v){
Node * node=new Node(v);
if(!p){
return node;
}
if(v < p->d){ //左子树
if(p->l){
p->l=insert(p->l,v);
}else{
p->l=node;
}
}else{
if(p->r){
p->r=insert(p->r,v);
}else{
p->r=node;
}
}
// setHeight(p);
//平衡旋转代码
//end of 平衡旋转代码
return p;
}
第三步:编写高度获取与设置的辅助函数
高度获取:
int getHeight(Node* node){
if(node) return node->h; //如果非空返回这个结点的height
return ; //空节点的高度是0
}
高度设置:
void setHeight(Node* node){ //取左右子树高度的最大值,记得+1
node->h=max(getHeight(node->l),getHeight(node->r))+;
}
第四步:编写平衡旋转函数
当左右子树的height相差为2时,就要调用平衡旋转函数进行旋转。一共有4种旋转模式:
(注:一下图片采用自博客:http://www.cnblogs.com/Camilo/p/3917041.html,如果侵权请联系我删除)
左子树左结点引起的不平衡:
Node* LL(Node* node){
Node* re=node->l;
node->l=re->r;
re->r=node;
setHeight(node); //注意:先进行这一步。因为node是re的子结点,从下往上调整
setHeight(re);
return re;
}

右子树右结点引起的不平衡:
Node* RR(Node* node){
Node* re=node->r;
node->r=re->l;
re->l=node;
setHeight(node);
setHeight(re);
return re;
}
(注:编写技巧是在LL函数的基础上,把所有的r写成l,把所有的l写成r,轮换对称思想)

左子树右结点引起的不平衡:
Node* LR(Node* node){
node->l=RR(node->l);
node=LL(node);
return node;
}

右子树左结点引起的不平衡:
Node* RL(Node* node){
node->r=LL(node->r);
node=RR(node);
return node;
}

第五步:在BST树的插入函数中编写平衡旋转代码:
Node* insert(Node* p,int v){
Node * node=new Node(v);
if(!p){
return node;
}
if(v < p->d){ //左子树
if(p->l){
p->l=insert(p->l,v);
}else{
p->l=node;
}
}else{
if(p->r){
p->r=insert(p->r,v);
}else{
p->r=node;
}
}
setHeight(p);
//平衡旋转代码
if(getHeight(p->l)-getHeight(p->r)==){ //左子树不平衡
if(getHeight(p->l->l)>getHeight(p->l->r)){//左结点不平衡
p=LL(p);
}else{ //右结点不平衡
p=LR(p);
}
}
if(getHeight(p->r)-getHeight(p->l)==){ //右子树不平衡
if(getHeight(p->r->l)>getHeight(p->r->r)){//左结点不平衡
p=RL(p);
}else{ //右结点不平衡
p=RR(p);
}
}
//end of 平衡旋转代码
return p;
}
打个OJ测试一下:1123. Is It a Complete AVL Tree
AC代码:
#include <stdio.h>
#include <queue>
#include <algorithm> using namespace std; typedef struct Node{
int d; //data
int h=; //height
struct Node* l=NULL;
struct Node* r=NULL;
Node(int d=):d(d){
}
}Node; int getHeight(Node* node){
if(node) return node->h; //如果非空返回这个结点的height
return ; //空节点的高度是0
} void setHeight(Node* node){ //取左右子树高度的最大值,记得+1
node->h=max(getHeight(node->l),getHeight(node->r))+;
} Node* LL(Node* node){
Node* re=node->l;
node->l=re->r;
re->r=node;
setHeight(node); //注意:先进行这一步。因为node是re的子结点,从下往上调整
setHeight(re);
return re;
} Node* RR(Node* node){
Node* re=node->r;
node->r=re->l;
re->l=node;
setHeight(node);
setHeight(re);
return re;
} Node* LR(Node* node){
node->l=RR(node->l);
node=LL(node);
return node;
} Node* RL(Node* node){
node->r=LL(node->r);
node=RR(node);
return node;
} Node* insert(Node* p,int v){
Node * node=new Node(v);
if(!p){
return node;
}
if(v < p->d){ //左子树
if(p->l){
p->l=insert(p->l,v);
}else{
p->l=node;
}
}else{
if(p->r){
p->r=insert(p->r,v);
}else{
p->r=node;
}
}
setHeight(p);
//平衡旋转代码
if(getHeight(p->l)-getHeight(p->r)==){ //左子树不平衡
if(getHeight(p->l->l)>getHeight(p->l->r)){//左结点不平衡
p=LL(p);
}else{ //右结点不平衡
p=LR(p);
}
}
if(getHeight(p->r)-getHeight(p->l)==){ //右子树不平衡
if(getHeight(p->r->l)>getHeight(p->r->r)){//左结点不平衡
p=RL(p);
}else{ //右结点不平衡
p=RR(p);
}
}
//end of 平衡旋转代码
return p;
} int cnt=; int main(){
// freopen("I:\\pat\\树\\AVL\\1123_2.txt","r",stdin);
int n,t;
scanf("%d",&n);
Node * root;
for(int i=;i<n;i++){
scanf("%d",&t);
root=insert(root,t);
}
queue<Node*> q;
q.push(root);
bool findNull=;
bool yes=;
bool after=;
while(!q.empty()){
Node* t=q.front();
q.pop();
printf("%d",t->d);
cnt++;
if(cnt!=n)
printf(" ");
if(t->l){
q.push(t->l);
if(after) yes=;
}
else after=;
if(t->r){
q.push(t->r);
if(after) yes=;
}
else after=;
}
puts("");
puts(yes?"YES":"NO");
return ;
}
一步一步编写AVL树的更多相关文章
- 一步一步写平衡二叉树(AVL树)
平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...
- AVL树的插入与删除
AVL 树要在插入和删除结点后保持平衡,旋转操作必不可少.关键是理解什么时候应该左旋.右旋和双旋.在Youtube上看到一位老师的视频对这个概念讲解得非常清楚,再结合算法书和网络的博文,记录如下. 1 ...
- 一步一步教你编写与搭建自动化测试框架——python篇
[本文出自天外归云的博客园] 这两天用python写了一个自动化测试框架,取名为Auty.准备用来做Web方面的接口测试,以下为Auty框架一步一步的搭建过程——
- 一步一步理解线段树——转载自JustDoIT
一步一步理解线段树 目录 一.概述 二.从一个例子理解线段树 创建线段树 线段树区间查询 单节点更新 区间更新 三.线段树实战 -------------------------- 一 概述 线段 ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- AVL树的平衡算法(JAVA实现)
1.概念: AVL树本质上还是一个二叉搜索树,不过比二叉搜索树多了一个平衡条件:每个节点的左右子树的高度差不大于1. 二叉树的应用是为了弥补链表的查询效率问题,但是极端情况下,二叉搜索树会无限接近 ...
- 【数据结构】平衡二叉树—AVL树
(百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...
- 我的新发现:AVL树旋转的一个特性
关于AVL树旋转的代码网络上铺天盖地. 一些经典的实现方法如下: AVLTree SingleLeftRotation(AVLTree A) { AVLTree B = A->left; A-& ...
- 纸上谈兵:AVL树
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 二叉搜索树的深度与搜索效率 我们在树, 二叉树, 二叉搜索树中提到,一个有n个节点 ...
随机推荐
- Oracle性能调优之虚拟索引用法简介
本博客记录一下Oracle虚拟索引的用法,虚拟索引是定义在数据字典中的伪索引,可以说是伪列,没有修改的索引字段的.虚拟索引的目的模拟索引,不会增加存储空间的使用,有了虚拟索引,开发者使用执行计划的时候 ...
- 安卓 apk 嵌入H5页面只显示部分
安卓 apk 嵌入H5页面只显示部分(有空白页出现) 解决方案 没有加载的是js部分,需要在安卓那边加上一串代码 webView.getSetting().setDomStorageEnabled(t ...
- Java内部类是如何实现的
内部类(inner class)是定义在另一个类中的类. 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据. 内部类可以对同一个包中的其他类隐藏起来 当想定义一个回调函数且不想编写大量代 ...
- [转帖]银河麒麟Kydroid 2.0全新发布:原生支持海量安卓APP
银河麒麟Kydroid 2.0全新发布:原生支持海量安卓APP https://news.cnblogs.com/n/652299/将手机操作系统 转移到 桌面 跟chromebook 类似的策略吧 ...
- 运维开发实践——基于Sentry搭建错误日志监控系统
错误日志监控也可称为业务逻辑监控, 旨在对业务系统运行过程中产生的错误日志进行收集归纳和监控告警.似乎有那么点曾相识?没错... 就是提到的“APM应用性能监控”.但它又与APM不同,APM系统主要注 ...
- Mysql 错误 ERROR 1 (HY000) at line 1: Can't create/write to file '/home/kaizenly/cfg_dict.csv' (Errcode: 13 - Permission denied)
[1]问题描述 (1)执行SQL语句: use billing; select * from cfg_dict into outfile '/home/kaizenly/cfg_dict.csv' f ...
- 算法设计与分析(李春保)练习题答案v2
----------------------------------------------------- Page 1 --------------------------------------- ...
- SFTP 定时任务下载
1.上传 winscp.exe /console /command "option batch continue" "option confirm off" & ...
- ipxe(可选):winboot:网络引导(启动)wim格式的windows PE系统:配置文件写法
ipxe 无盘[网络]引导wim格式的pe系统 wimboot引导程序需要为其提供4个内核参数 bcd bootmgr boot.sdi boot.wim 所需文件附件 以下是我的可用的ipxe的配置 ...
- 【ELK】elasticsearch使用bulk 导入批量的数据集文件报错:Validation Failed: 1: no requests added
执行命令如下: curl -XPOST http://192.168.6.16:9200/my_new_index/user/_bulk?pretty --data-binary @/cjf/es/e ...