class AVLwithparent {
constructor(key) {
this
.left =
null
;
this
.right =
null
;
this
.key = key;
this
.par =
null
;
this
.height = 1;
}
}
function
printpreorder(root) {
if
(root !==
null
) {
console.log(`Node: ${root.key}, Parent Node: ${root.par ? root.par.key : 'NULL
'}`);
// Recur to the left subtree
printpreorder(root.left);
// Recur to the right subtree
printpreorder(root.right);
}
}
// Function to update the height of a node according to its children'
s node
's heights
function Updateheight(root) {
if (root !== null) {
// Store the height of the current node
let val = 1;
// Store the height of the left and right subtree
if (root.left !== null) {
val = root.left.height + 1;
}
if (root.right !== null) {
val = Math.max(val, root.right.height + 1);
}
// Update the height of the current node
root.height = val;
}
}
// Function to handle Left Left Case
function LLR(root) {
// Create a reference to the left child
const tmpnode = root.left;
// Update the left child of the root to the right child of the current left child of the root
root.left = tmpnode.right;
// Update parent pointer of left child of the root node
if (tmpnode.right !== null) {
tmpnode.right.par = root;
}
// Update the right child of tmpnode to root
tmpnode.right = root;
// Update parent pointer of tmpnode
tmpnode.par = root.par;
// Update the parent pointer of root
root.par = tmpnode;
// Update tmpnode as the left or the right child of its parent pointer according to its key value
if (tmpnode.par !== null && root.key < tmpnode.par.key) {
tmpnode.par.left = tmpnode;
} else {
if (tmpnode.par !== null) {
tmpnode.par.right = tmpnode;
}
}
// Make tmpnode as the new root
root = tmpnode;
// Update the heights
Updateheight(root.left);
Updateheight(root.right);
Updateheight(root);
Updateheight(root.par);
// Return the root node
return root;
}
// Function to handle Right Right Case
function RRR(root) {
// Create a reference to the right child
const tmpnode = root.right;
// Update the right child of the root as the left child of the current right child of the root
root.right = tmpnode.left;
// Update parent pointer of the right child of the root node
if (tmpnode.left !== null) {
tmpnode.left.par = root;
}
// Update the left child of the tmpnode to root
tmpnode.left = root;
// Update parent pointer of tmpnode
tmpnode.par = root.par;
// Update the parent pointer of root
root.par = tmpnode;
// Update tmpnode as the left or the right child of its parent pointer according to its key value
if (tmpnode.par !== null && root.key < tmpnode.par.key) {
tmpnode.par.left = tmpnode;
} else {
if (tmpnode.par !== null) {
tmpnode.par.right = tmpnode;
}
}
// Make tmpnode as the new root
root = tmpnode;
// Update the heights
Updateheight(root.left);
Updateheight(root.right);
Updateheight(root);
Updateheight(root.par);
// Return the root node
return root;
}
// Function to handle Left Right Case
function LRR(root) {
root.left = RRR(root.left);
return LLR(root);
}
// Function to handle Right Left Case
function RLR(root) {
root.right = LLR(root.right);
return RRR(root);
}
// Function to Balance the tree after deletion of a node
function Balance(root) {
// Store the current height of the left and right subtree
let firstheight = 0;
let secondheight = 0;
if (root.left !== null) {
firstheight = root.left.height;
}
if (root.right !== null) {
secondheight = root.right.height;
}
// If the current node is not Balanced
if (Math.abs(firstheight - secondheight) === 2) {
if (firstheight < secondheight) {
// Store the height of the left and right subtree of the current node'
s right subtree
let rightheight1 = 0;
let rightheight2 = 0;
if
(root.right.right !==
null
) {
rightheight2 = root.right.right.height;
}
if
(root.right.left !==
null
) {
rightheight1 = root.right.left.height;
}
if
(rightheight1 > rightheight2) {
root = RLR(root);
}
else
{
root = RRR(root);
}
}
else
{
let leftheight1 = 0;
let leftheight2 = 0;
if
(root.left.right !==
null
) {
leftheight2 = root.left.right.height;
}
if
(root.left.left !==
null
) {
leftheight1 = root.left.left.height;
}
if
(leftheight1 > leftheight2) {
root = LLR(root);
}
else
{
root = LRR(root);
}
}
}
return
root;
}
function
Insert(root, parent, key) {
if
(root ===
null
) {
root =
new
AVLwithparent(key);
if
(root ===
null
) {
console.log(
"Error in memory"
);
}
else
{
root.par = parent;
}
}
else
if
(root.key > key) {
root.left = Insert(root.left, root, key);
let firstheight = 0;
let secondheight = 0;
if
(root.left !==
null
) {
firstheight = root.left.height;
}
if
(root.right !==
null
) {
secondheight = root.right.height;
}
if
(Math.abs(firstheight - secondheight) === 2) {
if
(root.left !==
null
&& key < root.left.key) {
root = LLR(root);
}
else
{
root = LRR(root);
}
}
}
else
if
(root.key < key) {
root.right = Insert(root.right, root, key);
let firstheight = 0;
let secondheight = 0;
if
(root.left !==
null
) {
firstheight = root.left.height;
}
if
(root.right !==
null
) {
secondheight = root.right.height;
}
if
(Math.abs(firstheight - secondheight) === 2) {
if
(root.right !==
null
&& key < root.right.key) {
root = RLR(root);
}
else
{
root = RRR(root);
}
}
}
else
{
}
Updateheight(root);
return
root;
}
function
Delete(root, key) {
if
(root !==
null
) {
if
(root.key === key) {
if
(root.right ===
null
&& root.left !==
null
) {
if
(root.par !==
null
) {
if
(root.par.key < root.key) {
root.par.right = root.left;
}
else
{
root.par.left = root.left;
}
Updateheight(root.par);
}
root.left.par = root.par;
root.left = Balance(root.left);
return
root.left;
}
else
if
(root.left ===
null
&& root.right !==
null
) {
if
(root.par !==
null
) {
if
(root.par.key < root.key) {
root.par.right = root.right;
}
else
{
root.par.left = root.right;
}
Updateheight(root.par);
}
root.right.par = root.par;
root.right = Balance(root.right);
return
root.right;
}
else
if
(root.left ===
null
&& root.right ===
null
) {
if
(root.par.key < root.key) {
root.par.right =
null
;
}
else
{
root.par.left =
null
;
}
if
(root.par !==
null
) {
Updateheight(root.par);
}
root =
null
;
return
null
;
}
else
{
let tmpnode = root;
tmpnode = tmpnode.right;
while
(tmpnode.left !==
null
) {
tmpnode = tmpnode.left;
}
let val = tmpnode.key;
root.right = Delete(root.right, tmpnode.key);
root.key = val;
root = Balance(root);
}
}
else
if
(root.key < key) {
root.right = Delete(root.right, key);
root = Balance(root);
}
else
if
(root.key > key) {
root.left = Delete(root.left, key);
root = Balance(root);
}
if
(root !==
null
) {
Updateheight(root);
}
}
else
{
console.log(
"Key to be deleted could not be found"
);
}
return
root;
}
let root =
null
;
root = Insert(root,
null
, 9);
root = Insert(root,
null
, 5);
root = Insert(root,
null
, 10);
root = Insert(root,
null
, 0);
root = Insert(root,
null
, 6);
console.log(
"Before deletion:"
);
printpreorder(root);
root = Delete(root, 10);
console.log(
"After deletion:"
);
printpreorder(root);