平衡二叉搜索树 Slef-balancing binary search tree
平衡二叉树,首先要是一个二叉排序树(Binary Sort Tree),是对BST的优化。
基本介绍
平衡二叉树也叫平衡二叉搜索树(Slef-balancing binary search tree),又被称为AVL树,可以保证查询效率较高
特点
它是一颗空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。
常用实现方式
红黑树、AVL、替罪羊树、Treap、伸展树等
左旋转
1.创建一个新的节点 newNode
2.newNode.left =left
3.newNode.right=right.left
4.value = right.value
5.right=right.right
6.left=newLeft
双旋转
有时候单旋转,并不能解决问题;所以有双旋转。
package com.algorthm.tree.selfBalanceBinarySearchTree;
public class AVKTreeDemo {
public static void main(String[] args) {
int [] arr ={4,3,6,5,7,8};
AVLTree avlTree = new AVLTree();
for (int i = 0; i < arr.length; i++) {
avlTree.add(new Node(arr[i]));
}
//遍历
System.out.println("infixOrder");
avlTree.infixOrder();
System.out.println("树的高度:"+avlTree.getRoot().height());//4
System.out.println("左子树的高度"+avlTree.getRoot().leftHeight());//1
System.out.println("右子树的高度"+avlTree.getRoot().rightHeight());//3
System.out.println("当前的根结点"+avlTree.getRoot());
}
}
class AVLTree {
private Node root;
public Node getRoot(){
return root;
}
public Node search(int value) {
if (root == null) {
return null;
}else{
return root.search(value);
}
}
public Node searchParent(int value){
if(root==null){
return null;
}else{
return root.searchParent(value);
}
}
public int delRightTreeMin(Node node){
Node target=node;
while(target.left!=null){
target = target.left;
}
delNode(target.value);
return target.value;
}
public int delLeftTreeMax(Node node){
Node target=node;
while(target.right!=null){
target=target.right;
}
delNode(target.value);
return target.value;
}
public void delNode(int value){
if(root == null){
return ;
}else{
Node target = this.search(value);
if(target==null){
return;
}
if(root.left==null&& root.right==null){
root=null;
return;
}
Node parent = searchParent(value);
if(target.left==null && target.right==null){
}else if(target.left!=null && target.right!=null){
int minValue= delRightTreeMin(target);
target.value=minValue;
}else{
if(target.left!=null){
if(parent!=null){
if(parent.left.value== target.value){
parent.left=target.left;
}
if(parent.right.value== target.value){
parent.right=target.left;
}
}
}
if(target.right!=null){
if(parent!=null){
if(parent.left.value== target.value){
parent.left=target.right;
}
if(parent.right.value== target.value){
parent.right=target.right;
}
}
}
}
}
}
public void add(Node node){
if(root ==null){
root=node;
}else{
root.add(node);
}
}
public void infixOrder(){
if(root!=null){
root.infixOrder();
}else{
System.out.println("the tree is empty");
}
}
}
class Node {
int value;
Node left;
Node right;
public Node(int value) {
this.value = value;
}
//返回左子树的高度
public int leftHeight() {
if (left == null) {
return 0;
} else {
return left.height();
}
}
//返回右子树的高度
public int rightHeight() {
if (right == null) {
return 0;
} else {
return right.height();
}
}
//左旋转 为了降低右子树的高度
private void leftRotate(){
//1.创建新的节点,以当前跟结点的值
Node newNode = new Node(value);
//2.把新节点的左子树设置为当前结点的左子树
newNode.left=left;
//3.把新节点的右子树设置成当前结点的右子树的左子树
newNode.right=right.left;
//4.把当前结点的值替换成右子树的值
value=right.value;
//5.把当前结点的右子树设置为右子树的右子树
right=right.right;
//6.把当前结点的左子树(左子节点)设置成新的结点
left=newNode;
}
//右旋转 为了降低左子树的高度
private void rightRotate(){
Node newNode = new Node(value);
//1.
newNode.right=right;
//2.
newNode.left=left.right;
//3.
value=left.value;
//4.
left=left.left;
//5.
right=newNode;
}
//返回当前结点的高度, 以该结点为根结点的树的高度
public int height() {
return Math.max(left == null ? 0 : left.height(), right == null ? 0 : right.height()) + 1;
}
public Node search(int value) {
if (value == this.value) {
return this;
} else if (value < this.value) {
if (this.left == null) {
return null;
}
return this.left.search(value);
} else {
if (this.right == null) {
return null;
}
return this.right.search(value);
}
}
public Node searchParent(int value) {
if ((this.left != null && this.left.value == value) ||
this.right != null && this.right.value == value) {
return this;
} else {
if (value < this.value && this.left != null) {
return this.left.searchParent(value);
} else if (value >= this.value && this.right != null) {
return this.right.searchParent(value);
} else {
return null;
}
}
}
@Override
public String toString() {
return "Node [ value " + value + " ]";
}
public void add(Node node) {
if (node == null) {
return;
}
if (node.value < this.value) {
if (this.left == null) {
this.left = node;
} else {
this.left.add(node);
}
}
if (node.value > this.value) {
if (this.right == null) {
this.right = node;
} else {
this.right.add(node);
}
}
//当添加完一个结点后,(右子树的高度 - 左子树的高度) >1, 左旋转----降低右子树的高度
if(rightHeight() -leftHeight() >1){
//如果它的右子树的左子树的高度 大于 它的右子树的高度
if(right!=null && right.leftHeight()> right.rightHeight()){
//1.先对右子节点进行右旋转
right.rightRotate();
//然后再对当前结点进行左旋转
leftRotate();
}else{
//直接左旋转
leftRotate();//左旋转
}
return;//避免不必要的比较
}
//当添加完一个节点,(左子树高度 - 右子树高度) >1 ,右旋转----降低左子树的高度
if(leftHeight()-rightHeight() >1){
//如果当前的左子树的右子树高度大于它的左子树高度
if(left !=null &&left.rightHeight() >left.leftHeight()){
//1.先对当前结点的左节点(左子树)->左旋转
left.leftRotate();
//再对当结点进行右旋转
rightRotate();
}else{
//直接进行右旋转接口
rightRotate();
}
}
}
public void infixOrder() {
if (this.left != null) {
this.left.infixOrder();
}
System.out.println(this);
if (this.right != null) {
this.right.infixOrder();
}
}
}