高度平衡二叉树的构建_平衡二叉树建立及其增删改查(JAVA)

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

主要思路: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:这种调整是因为在失衡节点的右孩子的右子树插入结点造成的。

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

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

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

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

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

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

代码:

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

System.out.println("执行RL平衡调整!");

tree = RL(tree);

}

else{

System.out.println("执行RR平衡调整!");

tree = RR(tree);

}

}

if(value < tree.data)

tree.nextLeftTree = ChangeToBalance(tree.nextLeftTree,value);//注意一定要等于 值传递!!!!!!!

else

tree.nextRightTree = ChangeToBalance(tree.nextRightTree,value);

return tree;

}

//计算各节点左右子树高度

public void AddHeight(BalanceTree tree){

if(tree == null)

return;

AddHeight(tree.nextLeftTree);//上下顺序很重要

AddHeight(tree.nextRightTree);

tree.Lheight = maxHeight(tree.nextLeftTree);

tree.Rheight = maxHeight(tree.nextRightTree);

}

//辅助计算左右子树高度

public int maxHeight(BalanceTree tree){

if(tree != null)

return tree.Lheight >= 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);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值