java實現二叉平衡樹
阿新 • • 發佈:2022-04-21
1. java 實現二叉平衡樹
/** * 二叉平衡樹 * 規則: * 1.新節點預設的深度為1 * 2.左子樹和右子樹高度相差超過1 就是不平衡,需要進行旋轉操作 * 右旋操作 * 2.1 如果左左節點比左右節點高,那要先對左節點左旋,再對當前節點右旋。否則直接當前節點右旋。 * 左旋操作 * 2.2 如果右左節點高於右右節點,需要先對右點節點右旋,再對當前節點左旋。否則直接當前節點左旋。 * */ public class MyAVLTree { Integer data; // 資料 Integer depth; // 深度 初始時預設為1 MyAVLTree leftChild; // 左子樹 MyAVLTree rightChild; // 右子樹 MyAVLTree parent; // 父子樹 public MyAVLTree(Integer data) { this.data = data; this.depth = 1; } // 增 public void insert(MyAVLTree newMyAVLTree) { if (newMyAVLTree.data == data) { return; } // 插入左邊 if (data > newMyAVLTree.data) { if (leftChild == null) { leftChild = newMyAVLTree; newMyAVLTree.parent = this; } else { leftChild.insert(newMyAVLTree); } } else{ // 插入右邊 if (rightChild == null) { rightChild = newMyAVLTree; newMyAVLTree.parent = this; } else { rightChild.insert(newMyAVLTree); } } // 調節平衡 adjustBalenced(newMyAVLTree); } // 調整平衡 private void adjustBalenced(MyAVLTree newMyAVLTree) { newMyAVLTree.depth = getDepth(newMyAVLTree) ; // 父節點左子樹和右子樹深度對比,如果平衡,則再遞迴檢查父 if (checkedBalanced(newMyAVLTree)) { // null是根節點 if (newMyAVLTree.parent == null) { return; } adjustBalenced(newMyAVLTree.parent); return; } // 1.如果左左節點比左右節點高,那要先對左節點左旋,再對當前節點右旋。否則直接當前節點右旋。 if (getDepth(newMyAVLTree.leftChild) > getDepth(newMyAVLTree.rightChild)) { // if (getDepth(newMyAVLTree.leftChild.leftChild) < getDepth(newMyAVLTree.leftChild.rightChild)) { leftRevolve(newMyAVLTree.leftChild); rightRevolve(newMyAVLTree); } else { rightRevolve(newMyAVLTree); } adjustBalenced(newMyAVLTree); return; } // 如果右左節點高於右右節點,需要先對右點節點右旋,再對當前節點左旋。否則直接當前節點左旋。 if (getDepth(newMyAVLTree.leftChild) < getDepth(newMyAVLTree.rightChild)) { if (getDepth(newMyAVLTree.rightChild.leftChild) > getDepth(newMyAVLTree.rightChild.rightChild)) { rightRevolve(newMyAVLTree.rightChild); leftRevolve(newMyAVLTree); } else { leftRevolve(newMyAVLTree); } adjustBalenced(newMyAVLTree); } } // 右旋 private void rightRevolve(MyAVLTree newMyAVLTree) { final MyAVLTree parent = newMyAVLTree.parent; final MyAVLTree leftChild = newMyAVLTree.leftChild; if (parent != null) { parent.rightChild = leftChild; } newMyAVLTree.parent = leftChild; newMyAVLTree.leftChild = newMyAVLTree.leftChild.rightChild; newMyAVLTree.depth = getDepth(newMyAVLTree); leftChild.parent = parent; leftChild.rightChild = newMyAVLTree; leftChild.depth = getDepth(leftChild) ; } // 左旋 private void leftRevolve(MyAVLTree myAVLTree) { MyAVLTree right = myAVLTree.rightChild; final MyAVLTree parent = myAVLTree.parent; if (parent != null) { parent.leftChild = right; } myAVLTree.parent = right; myAVLTree.rightChild = myAVLTree.rightChild.leftChild; myAVLTree.depth = getDepth(myAVLTree); right.parent = parent; right.leftChild = myAVLTree; right.depth = getDepth(right) ; } // 檢查節點的左右子樹是否平衡 private boolean checkedBalanced(MyAVLTree myAVLTree) { return Math.abs(getDepth(myAVLTree.leftChild) - getDepth(myAVLTree.rightChild)) <=1; } // 得出節點的深度 private Integer getDepth(MyAVLTree newMyAVLTree) { if (newMyAVLTree == null) { return 1; } MyAVLTree left = newMyAVLTree.leftChild; MyAVLTree right = newMyAVLTree.rightChild; if (left == null && right == null) { return 1; } if (left == null && right != null) { return right.depth + 1; } if (left != null && right == null) { return left.depth + 1; } return left.depth > right.depth ? left.depth + 1 : right.depth + 1; } // 查詢root 節點 public MyAVLTree getRoot() { if (parent == null) { return this; } return parent.getRoot(); } // 當前節點是否為父節點 private Boolean isRoot(MyAVLTree myAVLTree) { return myAVLTree.parent == null; } // 刪 public Boolean del(Integer integer) { if (integer == null) { return false; } MyAVLTree delAVLTree = this.find(integer); if (delAVLTree == null) { return false; } MyAVLTree delParent = delAVLTree.parent; MyAVLTree left = delAVLTree.leftChild; MyAVLTree right = delAVLTree.rightChild; // 左右都沒 if (left == null && right == null) { if (delParent == null) { // 即當前樹僅一個節點,且刪除的就是這個節點 return true; } if (delAVLTree.equals(delParent.leftChild)) { delParent.leftChild = null; } else { delParent.rightChild = null; } adjustBalenced(delParent); return true; } // 左沒 右有 if (left == null && right != null) { if (delParent == null) { right.parent = null; return true; } delParent.rightChild = right; adjustBalenced(right); return true; } // 左沒 右有 if (left != null && right == null) { if (delParent == null) { left.parent = null; return true; } delParent.leftChild = left; adjustBalenced(left); return true; } // 兩邊都有 final MyAVLTree rightTemp= left.rightChild; left.rightChild = right; left.parent = delParent; right.parent = left; if (rightTemp != null) { left.insert(rightTemp); } else { adjustBalenced(left); } return true; } // 查 public MyAVLTree find(Integer value) { if (isRoot(this)) { findTree(value); } return getRoot().findTree(value); } // 從根節點開始查詢元素 private MyAVLTree findTree(Integer value) { if (this.data == value) { return this; } if (this.data > value && this.leftChild != null) { return this.leftChild.findTree(value); } if (this.data < value && this.rightChild != null) { return this.rightChild.findTree(value); } return null; } }
有個缺點,不能刪除自己