public class AVLTree> extends BinarySearchTree implements ITree, BinaryTree.INodeCreator{
private enum Balance {
LEFT_LEFT, LEFT_RIGHT, RIGHT_LEFT, RIGHT_RIGHT
};
public int height = 1;
public AVLTree(){
this.creator = this;
}
@Override
public boolean add(E data){
Node t = super.addAndGetNode(data);
AVLNode addedNode = (AVLNode)t;
while(addedNode != null){
addedNode.updateHeight();
balnaceAfterInsert(addedNode);
addedNode = (AVLNode) addedNode.parent;
}
return true;
}
@Override
public E remove(E data){
Node nodeToRemoved = this.getNode(data);
if (nodeToRemoved != null) {
Node replacementNode = this.getReplacementNode(nodeToRemoved);
// ìì íì ì ì¡°ì ëì´í ë
¸ë
AVLNode nodeToRefactor = null;
if (replacementNode != null) // ë¶ëª¨ë¶í°
nodeToRefactor = (AVLNode) replacementNode.parent;
if (nodeToRefactor == null) // ëì²´í ë
¸ëê° ëì¸ê²½ì°ë leaf ë
¸ë ì´ë¯ë¡ ìì í ë
¸ëì ë¶ëª¨ë¶í° ì ì¡°ì
nodeToRefactor = (AVLNode) nodeToRemoved.parent;
// ì¬ì¡°ì ë
¸ëê° ìì í ë
¸ëë ê°ë¤ë©´ ë¶ëª¨ë¶í°ê° ìë ëì²´í ë
¸ëë¶í°
if (nodeToRefactor != null && nodeToRefactor.equals(nodeToRemoved))
nodeToRefactor = (AVLNode) replacementNode;
replaceNodeWithNode(nodeToRemoved, replacementNode);
if (nodeToRefactor != null) {
while (nodeToRefactor != null) {
nodeToRefactor.updateHeight();
balanceAfterDelete(nodeToRefactor);
nodeToRefactor = (AVLNode) nodeToRefactor.parent;
}
}
}
return data;
}
private void balnaceAfterInsert(AVLNode node){
int balanceFactor = node.getBalanceFactor();
if(balanceFactor < -1 || balanceFactor > 1){
// í¬ê¸° ì°¨ì´ê° 2ë³´ë¤ ì»¤ì§
AVLNode parent = null;
AVLNode child = null;
Balance balnace = null;
if(balanceFactor < 0){
// ì¼ìª½ì ì¶ê°ë¨
parent = (AVLNode)node.left;
balanceFactor = parent.getBalanceFactor();
if(balanceFactor < 0){
// ì¶ê°ë ë
¸ëê° ë¶ëª¨ì ì¼ìª½ì
child = (AVLNode)parent.left;
balnace = Balance.LEFT_LEFT;
}else{
// ì¶ê°ë ë
¸ëì ë¶ëª¨ì ì¤ë¥¸ìª½ì
child = (AVLNode)parent.right;
balnace = Balance.LEFT_RIGHT;
}
}else{
// ì¤ë¥¸ìª½ì ì¶ê°ë¨
parent = (AVLNode)node.right;
balanceFactor = parent.getBalanceFactor();
if(balanceFactor < 0 ){
// ì¶ê°ë ë
¸ëê° ë¶ëª¨ì ì¼ìª½ì
child = (AVLNode)parent.left;
balnace = Balance.RIGHT_LEFT;
}else{
child = (AVLNode)parent.right;
balnace = Balance.RIGHT_RIGHT;
}
}
print();
if(balnace == Balance.LEFT_LEFT){
System.out.println("LL");
rotateRight(node);
}else if(balnace == Balance.LEFT_RIGHT){
System.out.println("LR");
rotateLeft(parent);
print();
rotateRight(node);
print();
}else if(balnace == Balance.RIGHT_LEFT){
System.out.println("RL");
rotateRight(parent);
rotateLeft(node);
}else if(balnace == Balance.RIGHT_RIGHT){
System.out.println("RR");
rotateLeft(node);
}
print();
node.updateHeight();
child.updateHeight();
parent.updateHeight();
}
}
private void balanceAfterDelete(AVLNode node) {
int balanceFactor = node.getBalanceFactor();
if (balanceFactor == -2 || balanceFactor == 2) {
// TODO
if (balanceFactor == -2) {
// ì¼ìª½ì´ ë ëì´ê° ëë¤
// 1. (LL) ì¼ìª½ ììì ì¼ìª½ì´ ëì´ê° ë ëë¤ë©´ => ì¤ë¥¸ìª½ íì (ë
¸ë) => ë
¸ë, ë
¸ëì ë¶ëª¨ ëì´ ì¬ì¡°ì
// 2. (LR) ì¼ìª½ ììì ì¤ë¥¸ìª½ì´ ëì´ê° ë ëë¤ë©´ => ì¼ìª½ íì (ì¼ìª½ìì),ì¤ë¥¸ìª½íì (ë
¸ë) => ë
¸ëì ë¶ëª¨, ë
¸ëì ì쪽ìì ëì´ ì¬ì¡°ì
}
else if(balanceFactor == 2){
// ì¤ë¥¸ìª½ì´ ë ëì´ê° ëë¤.
// 3. (RR) ì¤ë¥¸ìª½ ììì ì¤ë¥¸ìª½ì´ ëì´ê° ë ëë¤ë©´ => ì¼ìª½ íì (ë
¸ë) => ë
¸ë, ë
¸ëì ë¶ëª¨ ëì´ ì¬ì¡°ì
// 4. (RLL) ì¤ë¥¸ìª½ ììì ì¼ìª½ì´ ëì´ê° ë ëë¤ë©´ => ì¤ë¥¸ìª½ íì (ì¤ë¥¸ìª½),ì¼ìª½íì (ë
¸ë) => ë
¸ëì ë¶ëª¨, ë
¸ëì ì쪽ìì ëì´ ì¬ì¡°ì
}
}
}
@Override
public Node createNewNode(E element, Node parent) {
return (new AVLNode(element, parent));
}
protected static class AVLNode> extends Node{
public int height = 1;
protected AVLNode(E element,Node parent) {
super(element, parent);
}
protected void updateHeight() {
int leftHeight = 0;
int rightHeight = 0;
if (left != null) {
AVLNode leftNode = (AVLNode) left;
leftHeight = leftNode.height;
}
if (right != null) {
AVLNode rightNode = (AVLNode) right;
rightHeight = rightNode.height;
}
if (leftHeight > rightHeight) {
this.height = leftHeight + 1;
} else {
this.height = rightHeight + 1;
}
}
protected int getBalanceFactor(){
int leftHeight = 0;
int rightHeight = 0;
if(this.left != null){
AVLNode avlNode = (AVLNode)left;
leftHeight = avlNode.height;
}
if(this.right != null){
AVLNode avlNode = (AVLNode)right;
rightHeight = avlNode.height;
}
return rightHeight-leftHeight;
}
@Override
public String toString(){
return "element : " + element +" : height : "+ height+ " balanceFactor : " + getBalanceFactor();
}
}
}