Skip to content

Commit

Permalink
Merge pull request #193 from Jeffzholy/fix/chapter-10-AVLTree
Browse files Browse the repository at this point in the history
fix: Chapter 10 AVL tree insertNode and removeNode functions
  • Loading branch information
loiane authored May 17, 2022
2 parents 8a39b5c + f0fa8e5 commit 73b3db5
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 100 deletions.
45 changes: 19 additions & 26 deletions src/js/data-structures/avl-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ export default class AVLTree extends BinarySearchTree {
insertNode(node, key) {
if (node == null) {
return new Node(key);
} if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
}
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
node.left = this.insertNode(node.left, key);
} else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
node.right = this.insertNode(node.right, key);
} else {
return node; // duplicated key
node.right = this.insertNode(node.right, key);
}

// verify if tree is balanced
const balanceFactor = this.getBalanceFactor(node);
if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) {
Expand All @@ -116,7 +116,7 @@ export default class AVLTree extends BinarySearchTree {
node = this.rotationLL(node);
} else {
// Left right case
return this.rotationLR(node);
node = this.rotationLR(node);
}
}
if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) {
Expand All @@ -125,7 +125,7 @@ export default class AVLTree extends BinarySearchTree {
node = this.rotationRR(node);
} else {
// Right left case
return this.rotationRL(node);
node = this.rotationRL(node);
}
}
return node;
Expand All @@ -136,32 +136,25 @@ export default class AVLTree extends BinarySearchTree {
if (node == null) {
return node;
}

// verify if tree is balanced
const balanceFactor = this.getBalanceFactor(node);
if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) {
// Left left case
if (
this.getBalanceFactor(node.left) === BalanceFactor.BALANCED
|| this.getBalanceFactor(node.left) === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT
) {
return this.rotationLL(node);
}
// Left right case
if (this.getBalanceFactor(node.left) === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT) {
return this.rotationLR(node.left);
if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) {
// Left left case
node = this.rotationLL(node);
} else {
// Left right case
node = this.rotationLR(node);
}
}
if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) {
// Right right case
if (
this.getBalanceFactor(node.right) === BalanceFactor.BALANCED
|| this.getBalanceFactor(node.right) === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT
) {
return this.rotationRR(node);
}
// Right left case
if (this.getBalanceFactor(node.right) === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT) {
return this.rotationRL(node.right);
if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) {
// Right right case
node = this.rotationRR(node);
} else {
// Right left case
node = this.rotationRL(node);
}
}
return node;
Expand Down
108 changes: 34 additions & 74 deletions src/ts/data-structures/avl-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,102 +100,62 @@ export default class AVLTree<T> extends BinarySearchTree<T> {
protected insertNode(node: Node<T>, key: T) {
if (node == null) {
return new Node(key);
} else if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
}
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
node.left = this.insertNode(node.left, key);
} else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
node.right = this.insertNode(node.right, key);
} else {
return node; // duplicated key
node.right = this.insertNode(node.right, key);
}

// verify if tree is balanced
const balanceState = this.getBalanceFactor(node);

if (balanceState === BalanceFactor.UNBALANCED_LEFT) {
const balanceFactor = this.getBalanceFactor(node);
if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) {
if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) {
// Left left case
node = this.rotationLL(node);
} else {
// Left right case
return this.rotationLR(node);
node = this.rotationLR(node);
}
}

if (balanceState === BalanceFactor.UNBALANCED_RIGHT) {
if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) {
if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) {
// Right right case
node = this.rotationRR(node);
} else {
// Right left case
return this.rotationRL(node);
node = this.rotationRL(node);
}
}

return node;
}

protected removeNode(node: Node<T>, key: T) {
if (node == null) {
return null;
}

if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
// The key to be deleted is in the left sub-tree
node.left = this.removeNode(node.left, key);
} else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
// The key to be deleted is in the right sub-tree
node.right = this.removeNode(node.right, key);
} else {
// node is the node to be deleted
if (node.left == null && node.right == null) {
node = null;
} else if (node.left == null && node.right != null) {
node = node.right;
} else if (node.left != null && node.right == null) {
node = node.left;
} else {
// node has 2 children, get the in-order successor
const inOrderSuccessor = this.minNode(node.right);
node.key = inOrderSuccessor.key;
node.right = this.removeNode(node.right, inOrderSuccessor.key);
}
}

if (node == null) {
return node;
}

// verify if tree is balanced
const balanceState = this.getBalanceFactor(node);

if (balanceState === BalanceFactor.UNBALANCED_LEFT) {
// Left left case
if (
this.getBalanceFactor(node.left) === BalanceFactor.BALANCED ||
this.getBalanceFactor(node.left) === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT
) {
return this.rotationLL(node);
}
// Left right case
if (this.getBalanceFactor(node.left) === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT) {
return this.rotationLR(node.left);
}
}

if (balanceState === BalanceFactor.UNBALANCED_RIGHT) {
// Right right case
if (
this.getBalanceFactor(node.right) === BalanceFactor.BALANCED ||
this.getBalanceFactor(node.right) === BalanceFactor.SLIGHTLY_UNBALANCED_RIGHT
) {
return this.rotationRR(node);
}
// Right left case
if (this.getBalanceFactor(node.right) === BalanceFactor.SLIGHTLY_UNBALANCED_LEFT) {
return this.rotationRL(node.right);
}
}

return node;
node = super.removeNode(node, key); // {1}
if (node == null) {
return node;
}

// verify if tree is balanced
const balanceFactor = this.getBalanceFactor(node);
if (balanceFactor === BalanceFactor.UNBALANCED_LEFT) {
if (this.compareFn(key, node.left.key) === Compare.LESS_THAN) {
// Left left case
node = this.rotationLL(node);
} else {
// Left right case
node = this.rotationLR(node);
}
}
if (balanceFactor === BalanceFactor.UNBALANCED_RIGHT) {
if (this.compareFn(key, node.right.key) === Compare.BIGGER_THAN) {
// Right right case
node = this.rotationRR(node);
} else {
// Right left case
node = this.rotationRL(node);
}
}
return node;
}
}

0 comments on commit 73b3db5

Please sign in to comment.