平衡二叉樹(AVL樹)一圖一步驟程式碼實現左旋右旋,左右平衡操作
阿新 • • 發佈:2018-12-25
/** * @version 建立時間: 2017-11-21 下午10:10:27 * 類說明:AVL樹 */ public class AVLTree<E extends Comparable<E>> { Node<E> root; int size = 0; private static final int LH = 1; private static final int RH = -1; private static final int EH = 0;
/** * 類說明:定義類 */ public classNode<E extends Comparable<E>> { E elemet; int balance = 0; Node<E> left; Node<E> right; Node<E> parent; public Node(E elem, Node<E> pare) { this.elemet = elem; this.parent = pare; } public E getElemet() { return elemet; } public void setElemet(E elemet) { this.elemet = elemet; } public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } public Node<E> getLeft() { return left; } public voidsetLeft(Node<E> left) { this.left = left; } public Node<E> getRight() { return right; } public void setRight(Node<E> right) { this.right = right; } public Node<E> getParent() { return parent; } public void setParent(Node<E> parent) { this.parent = parent; } }
/** * 左旋(對節點X進行左旋) * r γ α β
* 如上圖 */ public void left_rotate(Node<E> x){ if(x==null){ return ; } Node<E> Y=x.left; Node<E> parent=x.parent; // step1: x的右子 指向 β x.right=Y.left; if(Y.left!=null){ Y.left.parent=x; } // step2: Y的左子 指向 X Y.parent=x.parent; if(x.parent==null){ root=Y; }else{ if(parent.left==x){ parent.left= Y; }else if(parent.right==x){ parent.right= Y; } } // step3: x的父指向 Y Y.left=x; x.parent=Y;
}
/**
* 右旋(對節點Y進行右旋) * r γ α β */ public void right_rotate(Node<E> Y){ if(Y==null){ return ; } Node<E> x=Y.left; Node<E> parent=Y.parent; // step1: Y的左子 指向 β Y.left=x.right; if(x.right !=null){ x.right.parent=Y; } // step2: X的右子 指向 Y Y.parent=x.parent; if(x.parent==null){ root=Y; }else{ if(parent.left==Y){ parent.left= x; }else if(parent.right==Y){ parent.right= x; } } // step3: x的父指向 parent x.right=Y; Y.parent=x;
}
/** * 右平衡操作,即結點t的不平衡是因為右子樹過深 */ public void rightBalance(Node<E> t){ Node<E> tr = t.right; switch (tr.balance) { case RH://如果新的結點插入到t的右孩子的右子樹中,則直接進行左旋操作即可
left_rotate(t); t.balance = EH; tr.balance = EH; break; case LH://如果新的結點插入到p的右孩子的左子樹中,則需要進行分情況討論
Node<E> trl = tr.left; switch (trl.balance) { case LH://情況a:當p的右孩子的左子樹根節點的balance = LH
t.balance = EH; tr.balance = RH; trl.balance = EH; break; case RH://情況b:當p的右孩子的左子樹根節點的balance = RH
t.balance = LH; tr.balance = EH; trl.balance = EH; break; case EH://情況C:當p的右孩子的左子樹根節點的balance = EH
t.balance = EH; tr.balance = EH; trl.balance = EH; break; } //旋轉 right_rotate(t.right); left_rotate(t); break; case EH: break; } }
/** * 左平衡 */ public void leftBalance(Node<E> t){ Node<E> tl=t.right; switch (tl.balance) { case RH://如果新的結點插入到t的左孩子的左子樹中,則直接進行右旋操作即可
right_rotate(t); tl.balance=EH; t.balance=EH; break; case LH://如果新的結點插入到t的左孩子的右子樹中,則需要進行分情況討論
Node<E> tlr = tl.right; switch (tlr.balance) { case RH://情況a:當t的左孩子的右子樹根節點的balance = RH
t.balance=EH; tl.balance=LH; tlr.balance=EH; break; case LH://情況b:當p的左孩子的右子樹根節點的balance = LH
t.balance=RH; tl.balance=EH; tlr.balance=EH; break; case EH://情況c:當p的左孩子的右子樹根節點的balance = EH
t.balance=EH; tl.balance=EH; tlr.balance=EH; break; default: break; } left_rotate(t.left); right_rotate(t); break; default: break; } }