首先平衡二叉树是建立在二叉查找树之上的二叉树,需要明白的概念是左旋和右旋,二者代码如下:

void rotateLL(Node *&bbst)
/* LL型平衡调整:单向右旋平衡处理 */
{Node *lc;lc = bbst->lchild;bbst->lchild = lc->rchild;lc->rchild = bbst;bbst = lc;
}
void rotateRR(Node *&bbst)
/* RR型平衡调整:单向左旋平衡处理 */
{Node *rc;rc = bbst->rchild;bbst->rchild = rc->lchild;rc->lchild = bbst;bbst = rc;
}

用正数数组{3,2,5,1,4}建立一个二叉查找树,并进行右旋和左旋的处理,结果如下图:

下面是我写的平衡二叉查找树的c++代码,参考了《数据结构》-彭波算法8-8~8-12,期间在书中的算法中找到错误(书中算法8-12在二叉树右子树插入节点后的switch判断语句的case EH中,LH显然需要改为RH,否则不能得出正确结果),给出我的算法:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <iostream>using namespace std;#define LH 1 //左子树高
#define EH 0 //左右子树等高
#define RH -1//右子树高/* 整形二叉树节点 */
typedef struct Node {int data;int bf; /* 平衡因子 */struct Node *lchild, *rchild;
} Node, *BBST;void rotateLL(Node *&bbst)
/* LL型平衡调整:单向右旋平衡处理 */
{Node *lc;lc = bbst->lchild;bbst->lchild = lc->rchild;lc->rchild = bbst;bbst = lc;
}
void rotateRR(Node *&bbst)
/* RR型平衡调整:单向左旋平衡处理 */
{Node *rc;rc = bbst->rchild;bbst->rchild = rc->lchild;rc->lchild = bbst;bbst = rc;
}
void rotateLR(Node *&bbst)
/* LR型平衡调整:先左后右双向旋转平衡处理 */
{Node *lc, *rd;lc = bbst->lchild;//lc指向bbst的左子树switch(lc->bf) //bbst左子树进行平衡分析{case LH:  //新节点插入在bbst的左孩子左子树,则做LL处理bbst->bf = lc->bf = EH;rotateLL(bbst);break;case RH: //新节点插入在bbst的左孩子右子树,则做LR处理rd = lc->rchild;switch(rd->bf)//修改bbst和左孩子的平衡因子{case LH: bbst->bf = RH; lc->bf = EH;break;case EH: bbst->bf = lc->bf = EH;break;case RH: bbst->bf = EH; lc->bf = LH;break;}rd->bf = EH;rotateRR(bbst->lchild);//对bbst的左子树作RR处理rotateLL(bbst);   //对bbst作LL处理break;}
}void rotateRL(Node *&bbst)
/* RL型平衡调整:先右后左双向旋转平衡处理 */
{Node *rc, *ld;rc = bbst->rchild; //rc指向bbst的右子树的根节点switch(rc->bf) //检查bbst的右子树的平衡情况,并做处理{case RH:  //新节点插入在bbst的右孩子右子树,作RR处理bbst->bf = rc->bf = EH;rotateRR(bbst);break;case LH:   //新节点插入在bbst的右孩子左子树,作RL处理ld = rc->lchild; //令ld指向bbst的右孩子的左子树的根节点switch(ld->bf)  //修改bbst和右孩子的平衡因子{case LH: bbst->bf = LH; rc->bf = EH;break;case EH: bbst->bf = rc->bf = EH;break;case RH: bbst->bf = EH; rc->bf = RH;break;}ld->bf = EH;rotateLL(bbst->rchild); //对bbst的右子树作LL处理rotateRR(bbst);  //对bbst作RR处理break;}
}int insertBBSTNode(int data, Node *&bbst, int &high)
/* 插入节点Node */
{if(bbst == NULL){bbst = new Node;//(Node*)malloc(sizeof(Node));bbst->data = data;bbst->lchild = NULL;bbst->rchild = NULL;bbst->bf = EH;high = 1;}else {if(data == (bbst->data)){cout<<data<<"already exist.\n";high = 0;return 0;}else if(data < (bbst->data)){if(!insertBBSTNode(data, bbst->lchild, high)){return 0;  //不插入}if(high) //成功插入到左子树,且左子树变高了{switch(bbst->bf) {case LH:   //插入前左子树比右子树高rotateLR(bbst); //左平衡处理high = 0;  //处理后左右子树等高break;case EH:   //插入前左子树右子树等高bbst->bf = LH; //插入后左子树增高high = 1; //树变高break;case RH:  //插入前右子树比左子树高bbst->bf = EH;//插入后左右子树等高high = 0;//树未增高break;}}}else{if(!insertBBSTNode(data, bbst->rchild, high)){return 0;}if(high){switch(bbst->bf){case LH:bbst->bf = EH;high = 0;break;case EH:bbst->bf = RH;high = 1;break;case RH:rotateRL(bbst);high = 0;break;}}}}return 1;
}int insertArray2BBST(Node *&bbst, int *v, int num)
/* 向BST中插入数组 */
{int i=0, high = 0;while(i<num){//cout<<v[i]<<endl;insertBBSTNode(v[i], bbst, high);i++;}return 1;
}
void Traverse(Node *bbst, int type)
/* 1-先序遍历,2-中序遍历,3-后序遍历 */
{  if(bbst == NULL)  return;  else{ switch(type){case 1:cout<<bbst->data<<" - "; Traverse(bbst->lchild,type);  Traverse(bbst->rchild,type);  break;case 2:Traverse(bbst->lchild,type);  cout<<bbst->data<<" - "; Traverse(bbst->rchild,type);break;case 3:Traverse(bbst->lchild,type); Traverse(bbst->rchild,type); cout<<bbst->data<<" - "; break;default:cout<<"please type = 1,2,3"<<endl;break;}}
} int main( int argc, char **argv)
{int *v1, *v2;int n1 = 5, n2 = 1;int array1[] = {1,2,3,4,5};int array2[] = {1};v1 = array1;v2 = array2;Node *bbst = NULL;insertArray2BBST(bbst,v1,n1);insertArray2BBST(bbst,v2,n2);Traverse(bbst,1);cout<<endl;Traverse(bbst,2);cout<<endl;Traverse(bbst,3);cout<<endl;//rotateLL(bbst);//rotateLR(bbst);//Traverse(bbst,1);cout<<endl;//rotateRR(bbst);//Traverse(bbst,1);cout<<endl;return 1;
}

改程序的运行结果为:

D:\test>g++ BBST.cpp
D:\test>a.exe
1already exist.
2 - 1 - 4 - 3 - 5 -前序遍历
1 - 2 - 3 - 4 - 5 -中序遍历
1 - 3 - 5 - 4 - 2 -后序遍历

再次修改输入的字符串进行测试:

int n1 = 13, n2 = 1;
int array1[] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int array2[] = {1};

结果为:

D:\test>g++ BBST.cpp
D:\test>a.exe
1already exist.
8 - 4 - 2 - 1 - 3 - 6 - 5 - 7 - 10 - 9 - 12 - 11 - 13 -前序遍历
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 -中序遍历
1 - 3 - 2 - 5 - 7 - 6 - 4 - 9 - 11 - 13 - 12 - 10 - 8 -后序遍历

平衡二叉查找树的构造与遍历(C++)相关推荐

  1. 构造avl树_图解 AVL 自平衡二叉查找树及 java 实现

    思维导图 AVL树 AVL树是根据它的发明者G.M. Adelson-Velsky和E.M. Landis命名的. 它是最先发明的自平衡二叉查找树(Self-balancing binary sear ...

  2. 数据结构与算法之美笔记——基础篇(中):树,二叉树,二叉查找树,平衡二叉查找树,红黑树,递归树,堆

    树: A 节点就是 B 节点的父节点,B 节点是 A 节点的子节点.B.C.D 这三个节点的父节点是同一个节点,所以它们之间互称为兄弟节点.我们把没有父节点的节点叫作根节点,也就是图中的节点 E.我们 ...

  3. 平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】...

    平衡树初阶--AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是 ...

  4. 一看就懂的二叉查找树和平衡二叉查找树

    二叉查找树是一种特殊的二叉树,它可以组织动态数据集合,可以支持数据的快速插入,删除和查找操作.之前我们讨论过哈希表,他的,查找,插如和删除的时间复杂度是O(1),既然哈希表这么高效,那么为什么还需要二 ...

  5. 统计学习方法第三章作业:一般k邻近、平衡kd树构造、kd树邻近搜索算法代码实现

    一般k邻近 import numpy as np import matplotlib.pyplot as pltclass K_near:def __init__(self,X,Y,K=5,p=2): ...

  6. 平衡二叉查找树 AVL 的实现

    不同结构的二叉查找树,查找效率有很大的不同(单支树结构的查找效率退化成了顺序查找).如何解决这个问题呢?关键在于如何最大限度的减小树的深度.正是基于这个想法,平衡二叉树出现了. 平衡二叉树的定义 (A ...

  7. 平衡二叉查找树的构建

    平衡二叉查找树的构建 笔者最近在数据结构的学习过程中,觉得有必要将重要的内容记录下来,供自己以后复习使用.以下内容若有错误之处还请指出. 1. 概念 二叉树中结点的平衡因子Balance Factor ...

  8. 判断整数序列是不是二叉查找树的后序遍历结果

    转自:http://blog.csdn.net/tianshuai11/article/details/7068755 判断整数序列是不是二叉查找树的后序遍历结果 题目:输入一个整数数组,判断该数组是 ...

  9. C++AVL树(自平衡二叉查找树)(附完整源码)

    C++AVL树自平衡二叉查找树 node结构体定义 实现了以下几个接口 AVL树(自平衡二叉查找树)算法的完整源码(定义,实现,main函数测试) node结构体定义 typedef struct n ...

最新文章

  1. Ubuntu16.04 使用sudo cat EOF 编辑文件,提示Permission denied错误的解决办法
  2. Ubuntu 14.04.1 配置 Android 源码开发环境(jdk版本切换)(转载)
  3. SAP SD信用控制管理
  4. linux服务器健康检查,Linux 检查硬盘健康状态
  5. qq2006导致alt-tab切换失灵,还不知道怎么报告和解决(英文win2000)
  6. Undefined control sequence.l.463 \cita
  7. 6. php 基本语法
  8. Weex + Ui - Weex Conf 2018
  9. 曲线积分和曲面积分及其几何应用、物理应用
  10. C# AForge视频录像
  11. eXeScope 提取.exe/.dll中的图片资源
  12. 秒懂!何凯明的深度残差网络PPT是这样的|ICML2016 tutorial
  13. Spring的事务传播机制
  14. matlab画柱状图_附带调色、字体
  15. 超级高铁(Hyperloop)
  16. 作业帮-后台开发岗 面经
  17. python运行时不让电脑休眠_python – 在不中断程序的情况下休眠
  18. 设计表:多张表存储学生成绩及各种信息
  19. UE4 跑酷游戏-得分机制
  20. PHP如何去制作一个许愿墙,php许愿墙开发视频教程,php许愿墙源码

热门文章

  1. JVM学习-Java内存模型JMM
  2. 【2019.09.21】ICPC Latin American Regional-2017
  3. 《模式识别》自学笔记——(三)统计决策
  4. JavaScript通俗易懂(一)-变量提升
  5. python map filter reduce
  6. [BZOJ 3531] [Sdoi2014] 旅行 【离线+LCT】
  7. centos 6.0 安装 mysql 5.5.30_centos6.5下的mysql5.6.30安装
  8. nodejs计算时间间隔_NodeJs笔记:setTimeout 或 setInterval 的间隔时间执行
  9. 怎么判断我选了多少个复选框_7~8个月宝宝一天吃多少辅食,怎么安排?妈妈这样做,养出健康娃...
  10. putty怎么拷贝Linux下的日志,linux 下的 putty 如何复制与粘贴?