// Rotate the node to the left private static StringAVLNode rotateLeft(StringAVLNode t) { try { if (t.getRight() == null) { t.setRight(t.getRight().getLeft()); } else { StringAVLNode temp = t.getRight(); StringAVLNode temp2 = t.getRight().getLeft(); temp.setLeft(t); t.setRight(temp2); t = temp; } } catch (Exception e) { System.out.println("Failed Rotate Left"); } return t; }
private StringAVLNode replace(StringAVLNode t, StringAVLNode prev, StringAVLNode replacement) { int oldBalance, newBalance; if (replacement.getRight() == null) { // at the node that will replace the deleted node // move the replacement node – Recall there is no setVal if (prev != null) { prev.setRight(replacement.getLeft()); replacement.setLeft(t.getLeft()); replacement.setRight(t.getRight()); if (replacement.getBalance() != t.getBalance()) { replacement.setBalance(t.getBalance()); } } replacement.setRight(t.getRight()); t = replacement; } else { // find the old balance if (replacement.getRight() == null) { oldBalance = 5; } else { oldBalance = replacement.getRight().getBalance(); } t = replace(t, replacement, replacement.getRight()); // find the new balance if (replacement.getRight() == null) { newBalance = 3; // flag value replacement.setBalance(replacement.getBalance() - 1); } else { newBalance = replacement.getRight().getBalance(); } // update balance and rotate if needed if (oldBalance != 0 && newBalance == 0) { // if height decreased, correct the balance replacement.setBalance(replacement.getBalance() - 1); } if (replacement.getBalance() == -2) { // need to rotate? // there are now actually 3 cases because replacement.getLeft.getBalance() // could be -1, 0, or 1. if (replacement.getLeft().getBalance() == -1) { // single rotation right replacement = rotateRight(replacement); replacement.setBalance(0); replacement.getRight().setBalance(0); prev.setRight(replacement); } else if (replacement.getLeft().getBalance() == 0) { // single rotation right if (replacement.getLeft().getLeft() == null && replacement.getLeft().getRight() == null) { replacement = rotateRight(replacement); replacement.setBalance(0); replacement.getRight().setBalance(0); prev.setRight(replacement); } else { replacement = rotateRight(replacement); replacement.setBalance(1); replacement.getRight().setBalance(-1); prev.setRight(replacement); } } else { // replacement.getLeft().getBalance() == 1, double rotation case // Check if it is a x insert or a y insert. Update balances accordingly. if (replacement.getLeft().getRight().getBalance() == -1) { replacement.setLeft(rotateLeft(replacement.getLeft())); replacement = rotateRight(replacement); replacement.setBalance(0); replacement.getLeft().setBalance(0); replacement.getRight().setBalance(1); prev.setRight(replacement); } else if (replacement.getLeft().getRight().getBalance() == 1) { replacement.setLeft(rotateLeft(replacement.getLeft())); replacement = rotateRight(replacement); replacement.setBalance(0); replacement.getLeft().setBalance(-1); replacement.getRight().setBalance(0); prev.setRight(replacement); } else { // t.getLeft().getRight().getBalance() == 0 replacement.setLeft(rotateLeft(replacement.getLeft())); replacement = rotateRight(replacement); replacement.setBalance(0); replacement.getLeft().setBalance(0); replacement.getRight().setBalance(0); prev.setRight(replacement); } } } } return t; }
private StringAVLNode delete(StringAVLNode t, String str) { int oldBalance, newBalance; if (t == null) { // Do nothing if it is not in the tree } else if (str.compareToIgnoreCase(t.getItem()) < 0) { // get the old balance. if (t.getLeft() == null) { // still must deal with this special case in case // the element to be deleted is not in the tree oldBalance = 5; // flag value } else { oldBalance = t.getLeft().getBalance(); t.setLeft(delete(t.getLeft(), str)); } // get the new balance if (t.getLeft() == null) { newBalance = 1; // flag value if (oldBalance != 5) { t.setBalance(t.getBalance() + 1); } } else { newBalance = t.getLeft().getBalance(); } if (oldBalance != 0 && newBalance == 0) { // did the height decrease? // correct the balance t.setBalance(t.getBalance() + 1); } if (t.getBalance() == 2) { // need to rotate? // there are now actually 3 cases because t.getRight.getBalance() // could be -1, 0, or 1. if (t.getRight().getBalance() == 1) { // single rotation left t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); } else if (t.getRight().getBalance() == 0) { // single rotation left if (t.getRight().getLeft() == null && t.getRight().getRight() == null) { t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); } else { t = rotateLeft(t); t.setBalance(-1); t.getLeft().setBalance(1); } } else { // t.getRight().getBalance() == -1, double rotation case if (t.getRight().getLeft().getBalance() == -1) { t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(1); } else if (t.getRight().getLeft().getBalance() == 1) { t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(-1); t.getRight().setBalance(0); } else { // t.getRight().getLeft().getBalance() == 0 t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(0); } } } } else if (str.compareToIgnoreCase(t.getItem()) > 0) { if (t.getRight() == null) { // still must deal with this special case in case // the element to be deleted is not in the tree oldBalance = 5; // flag value } else { oldBalance = t.getRight().getBalance(); t.setRight(delete(t.getRight(), str)); } // get the new balance if (t.getRight() == null) { newBalance = -3; // flag value if (oldBalance != 5) { t.setBalance(t.getBalance() - 1); } } else { newBalance = t.getRight().getBalance(); } if (oldBalance != 0 && newBalance == 0) { // did the height decrease? // correct the balance t.setBalance(t.getBalance() - 1); } if (t.getBalance() == -2) { // need to rotate? // there are now actually 3 cases because t.getLeft.getBalance() // could be -1, 0, or 1. if (t.getLeft().getBalance() == -1) { // single rotation right t = rotateRight(t); t.setBalance(0); t.getRight().setBalance(0); } else if (t.getLeft().getBalance() == 0) { // single rotation right if (t.getLeft().getLeft() == null && t.getLeft().getRight() == null) { t = rotateRight(t); t.setBalance(0); t.getRight().setBalance(0); } else { t = rotateRight(t); t.setBalance(1); t.getRight().setBalance(-1); } } else { // t.getLeft().getBalance() == 1, double rotation case // Check if it is a x insert or a y insert. Update balances accordingly. if (t.getLeft().getRight().getBalance() == -1) { t.setLeft(rotateLeft(t.getLeft())); t = rotateRight(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(1); } else if (t.getLeft().getRight().getBalance() == 1) { t.setLeft(rotateLeft(t.getLeft())); t = rotateRight(t); t.setBalance(0); t.getLeft().setBalance(-1); t.getRight().setBalance(0); } else { // t.getLeft().getRight().getBalance() == 0 t.setLeft(rotateLeft(t.getLeft())); t = rotateRight(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(0); } } } } else { // t is the node to be deleted if (t.getLeft() == null) { // one of the easy cases // Replace t with right subtree t = t.getRight(); } else if (t.getRight() == null) { // the other easy case // Replace t with left subtree t = t.getLeft(); } else { // get the old balance // this is getLeft because we are using the inorder predecessor for replace // nullPrev is to check for the special case when prev is null and // update the balance of the replaced node properly. boolean nullPrev = false; int tBalance = 0; if (t.getLeft() == null) { oldBalance = 5; // flag value } else { oldBalance = t.getLeft().getBalance(); } if (t.getLeft().getRight() == null) { nullPrev = true; tBalance = t.getBalance(); } // find the replacement node and move it up t = replace(t, null, t.getLeft()); // get the new balance if (t.getLeft() == null) { newBalance = 3; // flag value t.setBalance(t.getBalance() + 1); } else { newBalance = t.getLeft().getBalance(); } // just like before, see if height decrease and if so // check to see if only need to change balance values or rotate if (oldBalance != 0 && newBalance == 0) { // if height decreased, correct the balance t.setBalance(t.getBalance() + 1); } if (nullPrev) { t.setBalance(tBalance + 1); } if (t.getBalance() == 2) { // need to rotate? // there are now actually 3 cases because t.getRight.getBalance() // could be -1, 0, or 1. if (t.getRight().getBalance() == 1) { // single rotation left t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); } else if (t.getRight().getBalance() == 0) { // single rotation left if (t.getRight().getLeft() == null && t.getRight().getRight() == null) { t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); } else { t = rotateLeft(t); t.setBalance(-1); t.getLeft().setBalance(1); } } else { // t.getRight().getBalance() == -1, double rotation case if (t.getRight().getLeft().getBalance() == -1) { t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(1); } else if (t.getRight().getLeft().getBalance() == 1) { t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(-1); t.getRight().setBalance(0); } else { // t.getRight().getLeft().getBalance() == 0 t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(0); } } } } } return t; }
private StringAVLNode insert(String str, StringAVLNode t) { int oldBalance, newBalance; if (t == null) { // easiest case – inserted node goes here t = new StringAVLNode(str); } else if (t.getItem() == str) { // already in the tree – do nothing } else if (str.compareToIgnoreCase(t.getItem()) < 0) { // str is smaller than this node – go left // get the old balance of the left child (where the insertion // is taking place) // oldBalance is the balance of the right/left subtree if (t.getLeft() == null) { oldBalance = -3; // flag value t.setBalance(t.getBalance() - 1); } else { oldBalance = t.getLeft().getBalance(); } t.setLeft(insert(str, t.getLeft())); newBalance = t.getLeft().getBalance(); if (oldBalance == 0 && newBalance != 0) { // did the height increase? t.setBalance(t.getBalance() - 1); } if (t.getBalance() == -2) { // out of balance – must rotate if (t.getLeft().getBalance() == -1) { // single rotation and balance update // the return value of rotateRight(t) is the new root after the rotation t = rotateRight(t); // The new root and its right child always has a balance of 0 after a rotate right. t.setBalance(0); t.getRight().setBalance(0); } else { // double rotation and balance update // once you get it right here, basically the // same code can be used in other places including delete // Check if it is a x insert or a y insert. Update balances accordingly. if (t.getLeft().getRight().getBalance() == -1) { t.setLeft(rotateLeft(t.getLeft())); t = rotateRight(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(1); } else if (t.getLeft().getRight().getBalance() == 1) { t.setLeft(rotateLeft(t.getLeft())); t = rotateRight(t); t.setBalance(0); t.getLeft().setBalance(-1); t.getRight().setBalance(0); } else { // t.getLeft().getRight().getBalance() == 0 t.setLeft(rotateLeft(t.getLeft())); t = rotateRight(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(0); } } } } // Cannot be just else because this allows duplicates in the tree. else if (str.compareToIgnoreCase(t.getItem()) > 0) { // str is bigger than this node. if (t.getRight() == null) { oldBalance = 3; // flag value t.setBalance(t.getBalance() + 1); } else { oldBalance = t.getRight().getBalance(); } t.setRight(insert(str, t.getRight())); newBalance = t.getRight().getBalance(); if (oldBalance == 0 && newBalance != 0) { t.setBalance(t.getBalance() + 1); } if (t.getBalance() == 2) { if (t.getRight().getBalance() == 1) { // the return value of rotateLeft(t) is the new root after the rotation t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); } else { // Check if it is a x insert or a y insert. Update balances accordingly. if (t.getRight().getLeft().getBalance() == -1) { t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(1); } else if (t.getRight().getLeft().getBalance() == 1) { t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(-1); t.getRight().setBalance(0); } else { // t.getRight().getLeft().getBalance() == 0 t.setRight(rotateRight(t.getRight())); t = rotateLeft(t); t.setBalance(0); t.getLeft().setBalance(0); t.getRight().setBalance(0); } } } } return t; }