因为上BST课的时候睡觉睡过了结果。。。,后者折腾了一个下午才写了出来,感谢http://blog.chinaunix.net/uid-24948645-id-3913917.html博客的详细解析,但是上面的不足之处在于代码是伪代码,基本实现不了,然后自己做了修改,改成c++的写法。

AVL树平衡二叉树数据结构

AVL树是最先发明的自平衡二叉查找算法,是平衡二叉树的一种。在AVL中任何节点的两个儿子子树的高度最大差别为1,所以它又被成为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来平衡这棵树。

假设把AVL树构造过程中需要重新平衡的节点叫做α。由于任意节点最多有两个儿子,因此高度不平衡时,α点的两颗子树的高度差2。这种不平衡可能出现在下面这四种情况:

1)  对α的左儿子的左子树进行一次插入(右旋)

其中D是新插入的节点,红色节点K2是失去平衡的节点。需要对K1和K2进行左旋调整即将K1作为根,将K2作为K1的左子树,K1的右子树调整为K2的左子树。如下图所示

进行右旋变换   

node* L_Ratate(node *K2)  //左旋
{node *K1;K1 = K2->Left;K2->Left = K1->Right;K1->Right = K2;//更新节点的高度return K1;
}

2)对α的右儿子的右子树进行一次插入(左旋)

将K2的右子树更改为K1的左子树,K1的左子树更改为K2即完成的右旋,如下图所示

进行左旋

node* R_Ratate(node* K2)
{node* K1;K1 = K2->Right;K2->Right = K1->Left;K1->Left = K2;//更新节点高度return K1;
}

3)对α的右儿子的左子树进行一次插入(右左双旋)

右左双旋:先对K1和K2进行左旋,然后在对K2和K3进行右旋,最终实现平衡。如下图所示

进行一次右旋进行一次左旋

node* DoubleL_Rotate(node* K3)//双向旋转(左右)
{K3->Left = R_Ratate(K3->Left);return L_Ratate(K3);
}

4)对α的左儿子的右子树进行一次插入(左右双旋)

左右双旋这里的左右指的是对α的左儿子的右子树进行插入时需要旋转。先对K1和K2进行右旋(跟第四种情况类似),然后再对K3和K2进行左旋,最终实现平衡。如下图所示

进行一次左旋进行一次右旋

node* DoubleR_Rotate(node* K3)//双向旋转(右左)
{K3->Right = L_Ratate(K3->Right);return R_Ratate(K3);
}

完整代码:

#include<iostream>
#include<algorithm>
using namespace std;
typedef struct Node
{int data;int bf;//用来表示平衡因子struct Node *Left,*Right;
} node;
node* L_Ratate(node *K2)  //左旋
{node *K1;K1 = K2->Left;K2->Left = K1->Right;K1->Right = K2;//更新节点的高度return K1;
}
node* R_Ratate(node* K2)
{node* K1;K1 = K2->Right;K2->Right = K1->Left;K1->Left = K2;//更新节点高度return K1;
}
node* DoubleL_Rotate(node* K3)//双向旋转(左右)
{K3->Left = R_Ratate(K3->Left);return L_Ratate(K3);
}
node* DoubleR_Rotate(node* K3)//双向旋转(右左)
{K3->Right = L_Ratate(K3->Right);return R_Ratate(K3);
}
int Height(node* P)
{if(P == NULL)return -1; //当构建根节点,或者是叶子节点的时候为-1+1正好为0elsereturn P->bf;
}node* create_bst(node* bst,int x)
{//cout<<"ok\n";if(!bst){//cout<<"ok\n";bst=new node;bst->data=x;bst->bf=0;bst->Left=bst->Right=NULL;}else if(x<bst->data){bst->Left=create_bst(bst->Left,x);if(Height(bst->Left)-Height(bst->Right)==2)//左子树插入节点所以高度是左子树高于右子树{if(x<bst->Left->data)//对α的左儿子的左子树进行一次插入,需要左旋bst=L_Ratate(bst);else//对α的左儿子的右子树进行一次插入,需要双旋bst=DoubleL_Rotate(bst);}}else if(x>bst->data)//右子树插入新节点{bst->Right = create_bst(bst->Right,x);if(Height(bst->Right) - Height(bst->Left)== 2)//因为是右子树插入新节点,所以高度是右子树高于左子树{if(x > bst->Right->data)//对α的右儿子的右子树进行一次插入,需要右旋bst = R_Ratate(bst);else//对α的右儿子的左子树进行一次插入,需要双旋bst = DoubleR_Rotate(bst);}}bst->bf = max(Height(bst->Left), Height(bst->Right)) + 1;//cout<<"test="<<bst->bf<<endl;return bst;
}
void InOrder(node* bst)
{if(!bst)return;else{InOrder(bst->Left);cout<<bst->data<<' '<<endl;InOrder(bst->Right);}
}
int main()
{int n;cout<<"请输入要构建的二叉平衡树序列长度"<<endl;cin>>n;cout<<"请输入要构建的二叉平衡树序列"<<endl;node *bst=NULL;for(int i=0; i<n; ++i){int d;cin>>d;bst=create_bst(bst,d);}cout<<"....输出...."<<endl;InOrder(bst);return 0;
}

手把手教你写平衡二叉树相关推荐

  1. 手把手教你写电商爬虫-第二课 实战尚妆网分页商品采集爬虫

    系列教程 手把手教你写电商爬虫-第一课 找个软柿子捏捏 如果没有看过第一课的朋友,请先移步第一课,第一课讲了一些基础性的东西,通过软柿子"切糕王子"这个电商网站好好的练了一次手,相 ...

  2. 手把手教你写一个生成对抗网络

    成对抗网络代码全解析, 详细代码解析(TensorFlow, numpy, matplotlib, scipy) 那么,什么是 GANs? 用 Ian Goodfellow 自己的话来说: " ...

  3. php注册程序,[PHP初级]手把手教你写注册程序 1

    [PHP初级]手把手教你写注册程序 1 实例内容 在此教程,我们将通过写一个用户注册程序,学习以下内容: 数据的传输与获取 信息的验证 pdo方式操作数据库 事务处理 前台显示文件:index.php ...

  4. python k线合成_手把手教你写一个Python版的K线合成函数

    手把手教你写一个Python版的K线合成函数 在编写.使用策略时,经常会使用一些不常用的K线周期数据.然而交易所.数据源又没有提供这些周期的数据.只能通过使用已有周期的数据进行合成.合成算法已经有一个 ...

  5. 手把手教你写Linux I2C设备驱动

    手把手教你写Linux I2C设备驱动 标签:Linux 设备 驱动 详解 i2c 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http:/ ...

  6. 手把手教你写DI_2_小白徒手撸构造函数注入

    在上一节:手把手教你写DI_1_DI框架有什么? 我们已经知道我们要撸哪些东西了 那么我们开始动工吧,这里呢,我们找小白同学来表演下 小白同学 :我们先定义一下我们的广告招聘纸有什么: 好,我们实现两 ...

  7. 手把手教你写DI_3_小白徒手支持 Singleton 和 Scoped 生命周期

    在上一节:手把手教你写DI_2_小白徒手撸构造函数注入 浑身绷带的小白同学:我们继续开展我们的工作,大家都知道 Singleton是什么,就是全局只有一个呗,我们就先从它开始,这个多简单,我们找个字典 ...

  8. 手把手教你写一个spring IOC容器

    本文分享自华为云社区<手把手教你写一个spring IOC容器>,原文作者:技术火炬手. spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术,成功 ...

  9. 手把手教你写网站:Python WEB开发技术实战

    摘要:本文详细介绍了Python WEB开发的基础入门.以一个博客站点的开发为例讲解了基于Django框架开发WEB站点的全过程.通过本文的学习可以快速掌握基于Django的Python WEB的开发 ...

最新文章

  1. 【C#文件锁】C#加密解密文件小工具
  2. java最简单的并查集(不想交集合)以及杭电1272
  3. matlab求实根,用弦截法任意实数方程求实根 用matlab 语言编程
  4. 用yum源配合源码包安装openresty、mariadb、php7服务
  5. leetcode79. 单词搜索(回溯算法)
  6. 因“智”而治,数据库自动驾驶时代大门即将开启!
  7. OpenAI发布CLIP模型快一年了,盘点那些CLIP相关让人印象深刻的工作
  8. java编写设置按钮随机背景色_java – 如何设置自定义按钮状态背景颜色?
  9. ant编辑java忽略注释_java – 注释不起作用
  10. mysql study_mysql_study_3
  11. c语言程序设计大一考题,C语言程序设计期末考试试题(含答案)
  12. FPGA之JESD204B接口——总体概要 实例 下
  13. pubg服务器未响应请求超时,PUBG进入游戏连接超时怎么办 | 手游网游页游攻略大全...
  14. 我国影视行业的痛点——影视链的目标
  15. QQ服务器维护一般多久,QQ扩列升级要多久?QQ扩列升级维护到什么时候结束
  16. 快递查询单号查询,追踪轨迹
  17. Java中实现快速傅里叶变换FFT
  18. php 斜杠字符,php-如何编码包含正斜杠的查询字符串?
  19. java 探测联网机_智能工厂-机联网
  20. 快手老司机与抖音小姐姐 ,终有一战?

热门文章

  1. php培训出生做微电影网站的,微电影分享网站织梦整站源码
  2. 大白菜pe解锁bitlocker_微PE工具箱 v2.1 官方版,最好用的 Win10PE 系统
  3. 机器人踩滑板_不死神草、飞行滑板…超2000种创新发明在这里展出
  4. php源码怎样安装mysql_安装MySQL
  5. 黄金分割小数点后100位小数的c语言编程,黄金分割数小数点后100位
  6. 名片识别信息分类python_python体验名片识别OCR
  7. jenkins 插件目录_10 个 Jenkins 实战经验,助你轻松上手持续集成
  8. hdu java_HDU-java实现1176
  9. 手机python3l运行_Python3 os.lchflags() 方法
  10. addeventlistener事件参数_Vue的钩子事件和程序化侦听