平衡二叉树:指的是左右子树高度差的绝对值不超过一的二叉排序树。

主要思路:1、用左高度跟右高度代替平衡因子,大于1进行L~调整,小于-1进行R~调整

2、每次插入都通过递归计算一次各结点高度,然后进行旋转调整

3、判断旋转操作时只需判断从失衡节点开始前两个节点  LL:左左左  、 RR:右右右  、 LR:左右~  、RL:右左~

坑:贯穿整个树的各个部分的就是值传递跟引用传递l,因为java中主要是值传递,详见:引用传递跟值传递详解

1、t后还附带孩6子节点,并不是单个节点(执行旋转操作时)

2、BalanceTree tree = t;  tree跟t指向同一个内存地址

3、BalanceTree tree = new BalanceTree();  tree跟t不是同一个地址

4、判断旋转操作时只需判断从失衡节点开始前两个节点  LL:左左左  、 RR:右右右  、 LR:左右~  、RL:右左~

5、递归一定要加上=号,否则可能造成值传不回来

想要实现平衡二叉树的建立,就要了解它的四种旋转调节方式:LL 、RR 、LR 、RL

LL:这种调整是因为在失衡节点的左孩子的左子树插入结点造成的。

RR:这种调整是因为在失衡节点的右孩子的右子树插入结点造成的。

java实现二叉树的构建 java二叉树的建立_System

LR:这种调整是因为在失衡节点的左孩子的右子树插入结点造成的。(两种情况)

左孩子的右子树的左孩子上添加导致失衡:

java实现二叉树的构建 java二叉树的建立_Java二叉树的建立和增删改_02

左孩子的右子树的右孩子上添加导致失衡:

java实现二叉树的构建 java二叉树的建立_System_03

RL:这种调整是因为在失衡节点的右孩子的左子树插入结点造成的。

右孩子的左子树的左孩子上插入导致失衡:

java实现二叉树的构建 java二叉树的建立_System_04

右孩子的左子树的右孩子上插入导致失衡:

java实现二叉树的构建 java二叉树的建立_System_05

代码:

package test;
/**
* @author HRX
* @version 创建时间:2018年10月3日 下午3:23:57
* 类说明
* 坑:1、t后还附带孩6子节点,并不是单个节点(执行旋转操作时)
* 2、BalanceTree tree = t; tree跟t指向同一个内存地址
* 3、BalanceTree tree = new BalanceTree(); tree跟t不是同一个地址
* 4、判断旋转操作时只需判断从失衡节点开始前两个节点 LL:左左左 、 RR:右右右 、 LR:左右~ 、RL:右左~
* 5、递归一定要加上=号,否则可能造成值传不回来
*/
public class BalanceTree {
private int data = 0;
private BalanceTree nextLeftTree;//左子树
private BalanceTree nextRightTree;//右子树
private int Lheight = 0;//左高度
private int Rheight = 0;//右高度
BalanceTree(){}//无参构造函数
BalanceTree(int xdata){
this.data = xdata;
}
//左旋调整
public BalanceTree LL(BalanceTree t){
BalanceTree t1 = new BalanceTree();
t1 = t.nextLeftTree;//t1指向t的左孩子
t.nextLeftTree = t1.nextRightTree;
t1.nextRightTree = t;//t1的右孩子指向t
return t1;
}
//右旋调整
public BalanceTree RR(BalanceTree t){
BalanceTree t1 = new BalanceTree();
t1 = t.nextRightTree;//t1指向t的右孩子
t.nextRightTree = t1.nextLeftTree;
t1.nextLeftTree = t;//t1的左孩子指向t
return t1;
}
public BalanceTree LR(BalanceTree t){
t.nextLeftTree = RR(t.nextLeftTree);
t = LL(t);
return t;
}
public BalanceTree RL(BalanceTree t){
t.nextRightTree = LL(t.nextRightTree);
t = RR(t);
return t;
}
//保持平衡操作
public BalanceTree ChangeToBalance(BalanceTree tree,int value){
if(tree == null)
return tree;
AddHeight(tree);
if(tree.Lheight - tree.Rheight > 1){
if(value < tree.data && value >tree.nextLeftTree.data){
System.out.println("执行LR平衡调整!");
tree = LR(tree);
}
else{
System.out.println("执行LL平衡调整!");
tree = LL(tree);
}
}
else if(tree.Lheight - tree.Rheight < -1){
if(value > tree.data && value = tree.Rheight ? tree.Lheight+1 : tree.Rheight+1;
else
return 0;
}
//遍历二叉树(中序遍历)
public static void ergodic (BalanceTree tree){
if(tree == null) return;
System.out.println(tree.data);
ergodic(tree.nextLeftTree);
ergodic(tree.nextRightTree);
}
//插入操作
public BalanceTree InTree(BalanceTree tree , int value){
BalanceTree tree2 = new BalanceTree();
if(tree.data == 0){
tree.data = value;
return tree;
}
tree2 = tree;
while(tree2 != null){
if(value < tree2.data){
System.out.println("左"+"value:"+value);
if(tree2.nextLeftTree != null){
tree2 = tree2.nextLeftTree;
}
else{
tree2.nextLeftTree = new BalanceTree(value);
break;
}
}
if(value >= tree2.data){
System.out.println("右"+"value:"+value);
if(tree2.nextRightTree != null){
tree2 = tree2.nextRightTree;
}
else{
tree2.nextRightTree = new BalanceTree(value);
break;
}
}
}
System.out.println((tree.Lheight +":::" +tree.Rheight));
tree = ChangeToBalance(tree,value);
return tree;
}
//查找节点
public BalanceTree findNode (BalanceTree tree ,int value){
while(tree !=null){
if(value < tree.data)
tree = tree.nextLeftTree;
else if(value > tree.data)
tree = tree.nextRightTree;
else if(value == tree.data)
return tree;
}
System.out.println("不存在要查询的数据!!!!");
return null;
}
//删除节点
public BalanceTree deleteNode (BalanceTree tree ,int value){
BalanceTree t = new BalanceTree();
BalanceTree parent = null;//一定要是null作为是否是删除根节点的判断
t = tree;
while(tree !=null&&value != t.data){
parent = t;
if(value < t.data)
t = t.nextLeftTree;
else if(value > t.data)
t = t.nextRightTree;
}
if(t == null)
System.out.println("不存在要删除的数据!!!!");
else if(t.nextLeftTree !=null && t.nextRightTree != null){
BalanceTree tree2 = t.nextRightTree;
BalanceTree pre = t;
while(tree2.nextLeftTree != null){
pre = tree2;
tree2 = tree2.nextLeftTree;
}
t.data = tree2.data;
if(pre == t)
pre.nextRightTree = tree2.nextRightTree;//不需要判断tree2.nextRightTree 是不是null,为空就给他赋值为空
else
pre.nextLeftTree = tree2.nextRightTree;
}
else{
BalanceTree tree3;
if(t.nextLeftTree == null) tree3 = t.nextRightTree;
else tree3 = t.nextLeftTree;
if(parent == null)
return tree3;
else if(parent.nextLeftTree == t) parent.nextLeftTree = tree3;
else parent.nextRightTree = tree3;
}
return tree;
}
//修改节点
public BalanceTree changeNode (BalanceTree tree ,int oldvalue ,int newvalue){
BalanceTree t = new BalanceTree();//会破坏排序树的性质
t = tree;
while(tree !=null){
if(oldvalue < t.data)
t = t.nextLeftTree;
else if(oldvalue > t.data)
t = t.nextRightTree;
else if(oldvalue == t.data){
t.data = newvalue;
return tree;
}
}
System.out.println("不存在要修改的数据!!!!");
return tree;
}
public static void main(String[] args) {
BalanceTree aBalanceTree = new BalanceTree();
//int[] num = {20,12,6,28,16,36,32,10,2,30,8};
int[] num = {20,12,6,28,16,36,32};
for(int n : num){
aBalanceTree = aBalanceTree.InTree(aBalanceTree, n);
}
ergodic(aBalanceTree);
System.out.println("-------------------------------");
BalanceTree aaa = aBalanceTree.deleteNode(aBalanceTree, 32);
ergodic(aaa);
}
}