高度平衡二叉树的构建_平衡二叉树建立及其增删改查(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);
}
}
總結
以上是生活随笔為你收集整理的高度平衡二叉树的构建_平衡二叉树建立及其增删改查(JAVA)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 私有云的优缺点_2019年中国云计算行业
- 下一篇: pb retrieve时停止工作_电机没