第一步:定义结构体

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树的更多相关文章

  1. 一步一步写平衡二叉树(AVL树)

    平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...

  2. AVL树的插入与删除

    AVL 树要在插入和删除结点后保持平衡,旋转操作必不可少.关键是理解什么时候应该左旋.右旋和双旋.在Youtube上看到一位老师的视频对这个概念讲解得非常清楚,再结合算法书和网络的博文,记录如下. 1 ...

  3. 一步一步教你编写与搭建自动化测试框架——python篇

    [本文出自天外归云的博客园] 这两天用python写了一个自动化测试框架,取名为Auty.准备用来做Web方面的接口测试,以下为Auty框架一步一步的搭建过程——

  4. 一步一步理解线段树——转载自JustDoIT

    一步一步理解线段树   目录 一.概述 二.从一个例子理解线段树 创建线段树 线段树区间查询 单节点更新 区间更新 三.线段树实战 -------------------------- 一 概述 线段 ...

  5. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  6. AVL树的平衡算法(JAVA实现)

      1.概念: AVL树本质上还是一个二叉搜索树,不过比二叉搜索树多了一个平衡条件:每个节点的左右子树的高度差不大于1. 二叉树的应用是为了弥补链表的查询效率问题,但是极端情况下,二叉搜索树会无限接近 ...

  7. 【数据结构】平衡二叉树—AVL树

    (百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...

  8. 我的新发现:AVL树旋转的一个特性

    关于AVL树旋转的代码网络上铺天盖地. 一些经典的实现方法如下: AVLTree SingleLeftRotation(AVLTree A) { AVLTree B = A->left; A-& ...

  9. 纸上谈兵:AVL树

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 二叉搜索树的深度与搜索效率 我们在树, 二叉树, 二叉搜索树中提到,一个有n个节点 ...

随机推荐

  1. java -jar 时指定内存大小

    java -jar -Xms1024m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M car.jar 说明: 1.堆内存:最小1024M,最大153 ...

  2. 另一种缓存,Spring Boot 整合 Ehcache

    用惯了 Redis ,很多人已经忘记了还有另一个缓存方案 Ehcache ,是的,在 Redis 一统江湖的时代,Ehcache 渐渐有点没落了,不过,我们还是有必要了解下 Ehcache ,在有的场 ...

  3. appium+python 多设备并行执行脚本【转】

    1.ready.py文件 def getport(): aport = random.randint(4700, 4900) # 判断端口是否被占用 while getDeviceInfo.is_op ...

  4. 如何将云上的Linux文件自动备份到本地服务器

    需求场景: 将云上一台Linux服务器文件备份到本地服务器,一周一备即可. 面对这样一个需求,我们可能面临下列几个问题, 备份方式:是云服务器推文件到本地服务器写入,还是本地服务器从云服务器拉文件?这 ...

  5. ThinkPad L460 拆机加ngff ssd与内存

    ThinkPad L460 拆机加ngff ssd与内存 参考链接:http://blog.sina.com.cn/s/blog_82793ae60102wgtp.html 原有配置:i5 6200U ...

  6. 【POI】java服务生成List数据集合,后台服务生成xlsx临时文件,并将临时文件上传到腾讯云上

    场景: java服务生成List数据集合,后台服务生成xlsx临时文件,并将临时文件上传到腾讯云上 今日份代码: 1.先是一个变量,作为文件名 private static final String ...

  7. SUSE 中文是乱码

    http://www.wo81.com/tec/os/suse/2014-04-30/186.html   操作系统:SUSE Linux Enterprise 11 问题:vi 打开文件,中文是乱码 ...

  8. 2019-11-29-WPF-绑定命令在-MVVM-的-CanExecute-和-Execute-在按钮点击都没触发可能的原因...

    原文:2019-11-29-WPF-绑定命令在-MVVM-的-CanExecute-和-Execute-在按钮点击都没触发可能的原因... title author date CreateTime c ...

  9. jQuery实现C#CheckBoxList模糊搜索

    前言 最近开发的一套系统中需要对商品进行管理,在选择商品时,要分别从品牌.型号.商品三个类别分别选择对应的选项才能找到需要的商品,三者的关系为:品牌包含型号,型号包含商品,因此使用了三个不同的 asp ...

  10. SpringBoot 打包成war

    1.修改pom.xml文件 <packaging>war</packaging> <properties> <project.build.sourceEnco ...