Question

In: Computer Science

Code using C++ A binary search tree is a data structure designed for efficient item insertion,...

Code using C++

A binary search tree is a data structure designed for efficient item insertion, deletion, and retrieval. These 3 operations share an average run time complexity of O(log(n)). Such time complexities are guaranteed whenever you are working with a balanced binary search tree. However, if you have a tree that begins leaning heavily to either its left or right side, then you can expect the performances of the insertion, deletion, and retrieval operations to degrade. As an example, consider a scenario in which 5 nodes with key values 1, 2, 3, 4, and 5 are inserted, in the order listed, into an initially empty binary search tree. The layout of the resulting tree would resemble a linearly linked list. As you all know, item insertion, deletion, and retrieval operations in a linearly linked list all carry an undesirable, worst-case time complexity of O(n). Fortunately, years ago, two mathematicians named Georgy Adelson-Velsky and Evgenii Landis designed specialized insertion and deletion functions for the binary search tree to ensure that the data structure always maintains its balance and thus avoids the linear time complexities plaguing the unbalanced trees.

Your task for this project is to implement the aptly named AVL tree, which requires both Adelson-Velsky and Evgenii’s specialized insertion and deletion functions. To determine whether or not your code is working properly, you will write a function that prints the heights of the binary nodes contained in your AVL tree. You may find it helpful to compare your results with those obtained from an interactive.

Along with this handout, we also provided you with starter code for a standard binary search tree. You need to modify the included insertion function and implement the AVL deletion and height printing functions. Keep in mind that the associated AVL algorithms will require you to add helper functions to the AVLTree class and possibly a few more variables to the BinaryNode struct. With that said, you are free to scrap the provided code and write everything from scratch.

Input

Input commands are read from the keyboard. Your program must continue to check for input until the quit command is issued. The accepted input commands are listed as follows:

i k : Insert node with key value k into AVL tree.

r k : Remove node with key value k from AVL tree. (When removing a node with two children, look to the InOrder predecessor in left subtree for the swapping node)

h : Print the height of each node using an inorder traversal. 1

p : Print the key value of each node using an inorder traversal.

q : Quit the program.

Output

Print the results of the p and h commands on one line using space as a delimiter. If the tree is empty when issuing the commands p or h, output the message Empty. If an attempt is made to remove a node not present in the tree, print No node. If an attempt is made to insert a node with a duplicate key value, print Duplicate without adding the new node to the tree. Do not worry about verifying the input format. For AVL deletion, we have 4 cases. In case 2 and case 3, the node to be removed (let's call it root) has a single child.  In theory, "root" needs to be removed and the child should be moved up. In practice, however, you don't want to simply remove the root, as the connection from the child node to root's parent will be lost. A better way would be copying the content (everything) of the child to root, and then delete the child. For case 4, we can choose either the InOrder predecessor or the successor as the replacement.

Sample Test

Case Use input redirection to redirect commands written in a file to the standard input, e.g. $ ./a.out < input1.dat.

Input 1

i 100 i 200 i 300 h p q

Output 1

1 2 1 100 200 300

Solutions

Expert Solution

*DELETION IN AVL TREE

#include<bits/stdc++.h>

using namespace std;

// An AVL tree node

class Node

{

    public:

    int key;

    Node *left;

    Node *right;

    int height;

};

// A utility function to get maximum

// of two integers

int max(int a, int b);

// A utility function to get height

// of the tree

int height(Node *N)

{

    if (N == NULL)

        return 0;

    return N->height;

}

// A utility function to get maximum

// of two integers

int max(int a, int b)

{

    return (a > b)? a : b;

}

/* Helper function that allocates a

   new node with the given key and

   NULL left and right pointers. */

Node* newNode(int key)

{

    Node* node = new Node();

    node->key = key;

    node->left = NULL;

    node->right = NULL;

    node->height = 1; // new node is initially

                      // added at leaf

    return(node);

}

// A utility function to right

// rotate subtree rooted with y

// See the diagram given above.

Node *rightRotate(Node *y)

{

    Node *x = y->left;

    Node *T2 = x->right;

    // Perform rotation

    x->right = y;

    y->left = T2;

    // Update heights

    y->height = max(height(y->left),

                    height(y->right)) + 1;

    x->height = max(height(x->left),

                    height(x->right)) + 1;

    // Return new root

    return x;

}

// A utility function to left

// rotate subtree rooted with x

// See the diagram given above.

Node *leftRotate(Node *x)

{

    Node *y = x->right;

    Node *T2 = y->left;

    // Perform rotation

    y->left = x;

    x->right = T2;

    // Update heights

    x->height = max(height(x->left),

                    height(x->right)) + 1;

    y->height = max(height(y->left),

                    height(y->right)) + 1;

    // Return new root

    return y;

}

// Get Balance factor of node N

int getBalance(Node *N)

{

    if (N == NULL)

        return 0;

    return height(N->left) -

           height(N->right);

}

Node* insert(Node* node, int key)

{

    /* 1. Perform the normal BST rotation */

    if (node == NULL)

        return(newNode(key));

    if (key < node->key)

        node->left = insert(node->left, key);

    else if (key > node->key)

        node->right = insert(node->right, key);

    else // Equal keys not allowed

        return node;

    /* 2. Update height of this ancestor node */

    node->height = 1 + max(height(node->left),

                           height(node->right));

    /* 3. Get the balance factor of this

        ancestor node to check whether

        this node became unbalanced */

    int balance = getBalance(node);

    // If this node becomes unbalanced,

    // then there are 4 cases

    // Left Left Case

    if (balance > 1 && key < node->left->key)

        return rightRotate(node);

    // Right Right Case

    if (balance < -1 && key > node->right->key)

        return leftRotate(node);

    // Left Right Case

    if (balance > 1 && key > node->left->key)

    {

        node->left = leftRotate(node->left);

        return rightRotate(node);

    }

    // Right Left Case

    if (balance < -1 && key < node->right->key)

    {

        node->right = rightRotate(node->right);

        return leftRotate(node);

    }

    /* return the (unchanged) node pointer */

    return node;

}

/* Given a non-empty binary search tree,

return the node with minimum key value

found in that tree. Note that the entire

tree does not need to be searched. */

Node * minValueNode(Node* node)

{

    Node* current = node;

    /* loop down to find the leftmost leaf */

    while (current->left != NULL)

        current = current->left;

    return current;

}

// Recursive function to delete a node

// with given key from subtree with

// given root. It returns root of the

// modified subtree.

Node* deleteNode(Node* root, int key)

{

     

    // STEP 1: PERFORM STANDARD BST DELETE

    if (root == NULL)

        return root;

    // If the key to be deleted is smaller

    // than the root's key, then it lies

    // in left subtree

    if ( key < root->key )

        root->left = deleteNode(root->left, key);

    // If the key to be deleted is greater

    // than the root's key, then it lies

    // in right subtree

    else if( key > root->key )

        root->right = deleteNode(root->right, key);

    // if key is same as root's key, then

    // This is the node to be deleted

    else

    {

        // node with only one child or no child

        if( (root->left == NULL) ||

            (root->right == NULL) )

        {

            Node *temp = root->left ?

                         root->left :

                         root->right;

            // No child case

            if (temp == NULL)

            {

                temp = root;

                root = NULL;

            }

            else // One child case

            *root = *temp; // Copy the contents of

                           // the non-empty child

            free(temp);

        }

        else

        {

            // node with two children: Get the inorder

            // successor (smallest in the right subtree)

            Node* temp = minValueNode(root->right);

            // Copy the inorder successor's

            // data to this node

            root->key = temp->key;

            // Delete the inorder successor

            root->right = deleteNode(root->right,

                                     temp->key);

        }

    }

    // If the tree had only one node

    // then return

    if (root == NULL)

    return root;

    // STEP 2: UPDATE HEIGHT OF THE CURRENT NODE

    root->height = 1 + max(height(root->left),

                           height(root->right));

    // STEP 3: GET THE BALANCE FACTOR OF

    // THIS NODE (to check whether this

    // node became unbalanced)

    int balance = getBalance(root);

    // If this node becomes unbalanced,

    // then there are 4 cases

    // Left Left Case

    if (balance > 1 &&

        getBalance(root->left) >= 0)

        return rightRotate(root);

    // Left Right Case

    if (balance > 1 &&

        getBalance(root->left) < 0)

    {

        root->left = leftRotate(root->left);

        return rightRotate(root);

    }

    // Right Right Case

    if (balance < -1 &&

        getBalance(root->right) <= 0)

        return leftRotate(root);

    // Right Left Case

    if (balance < -1 &&

        getBalance(root->right) > 0)

    {

        root->right = rightRotate(root->right);

        return leftRotate(root);

    }

    return root;

}

// A utility function to print preorder

// traversal of the tree.

// The function also prints height

// of every node

void preOrder(Node *root)

{

    if(root != NULL)

    {

        cout << root->key << " ";

        preOrder(root->left);

        preOrder(root->right);

    }

}

// Driver Code

int main()

{

Node *root = NULL;

    /* Constructing tree given in

    the above figure */

    root = insert(root, 9);

    root = insert(root, 5);

    root = insert(root, 10);

    root = insert(root, 0);

    root = insert(root, 6);

    root = insert(root, 11);

    root = insert(root, -1);

    root = insert(root, 1);

    root = insert(root, 2);

    /* The constructed AVL Tree would be

            9

        / \

        1 10

        / \ \

    0 5 11

    / / \

    -1 2 6

    */

    cout << "Preorder traversal of the "

            "constructed AVL tree is \n";

    preOrder(root);

    root = deleteNode(root, 10);

    /* The AVL Tree after deletion of 10

            1

        / \

        0 9

        / / \

    -1 5     11

        / \

        2 6

    */

    cout << "\nPreorder traversal after"

         << " deletion of 10 \n";

    preOrder(root);

    return 0;

}

INSERTION IN AVL TREE

#include<bits/stdc++.h>

using namespace std;

// An AVL tree node

class Node

{

    public:

    int key;

    Node *left;

    Node *right;

    int height;

};

// A utility function to get maximum

// of two integers

int max(int a, int b);

// A utility function to get the

// height of the tree

int height(Node *N)

{

    if (N == NULL)

        return 0;

    return N->height;

}

// A utility function to get maximum

// of two integers

int max(int a, int b)

{

    return (a > b)? a : b;

}

/* Helper function that allocates a

   new node with the given key and

   NULL left and right pointers. */

Node* newNode(int key)

{

    Node* node = new Node();

    node->key = key;

    node->left = NULL;

    node->right = NULL;

    node->height = 1; // new node is initially

                      // added at leaf

    return(node);

}

// A utility function to right

// rotate subtree rooted with y

// See the diagram given above.

Node *rightRotate(Node *y)

{

    Node *x = y->left;

    Node *T2 = x->right;

    // Perform rotation

    x->right = y;

    y->left = T2;

    // Update heights

    y->height = max(height(y->left),

                    height(y->right)) + 1;

    x->height = max(height(x->left),

                    height(x->right)) + 1;

    // Return new root

    return x;

}

// A utility function to left

// rotate subtree rooted with x

// See the diagram given above.

Node *leftRotate(Node *x)

{

    Node *y = x->right;

    Node *T2 = y->left;

    // Perform rotation

    y->left = x;

    x->right = T2;

    // Update heights

    x->height = max(height(x->left),    

                    height(x->right)) + 1;

    y->height = max(height(y->left),

                    height(y->right)) + 1;

    // Return new root

    return y;

}

// Get Balance factor of node N

int getBalance(Node *N)

{

    if (N == NULL)

        return 0;

    return height(N->left) - height(N->right);

}

// Recursive function to insert a key

// in the subtree rooted with node and

// returns the new root of the subtree.

Node* insert(Node* node, int key)

{

    /* 1. Perform the normal BST insertion */

    if (node == NULL)

        return(newNode(key));

    if (key < node->key)

        node->left = insert(node->left, key);

    else if (key > node->key)

        node->right = insert(node->right, key);

    else // Equal keys are not allowed in BST

        return node;

    /* 2. Update height of this ancestor node */

    node->height = 1 + max(height(node->left),

                        height(node->right));

    /* 3. Get the balance factor of this ancestor

        node to check whether this node became

        unbalanced */

    int balance = getBalance(node);

    // If this node becomes unbalanced, then

    // there are 4 cases

    // Left Left Case

    if (balance > 1 && key < node->left->key)

        return rightRotate(node);

    // Right Right Case

    if (balance < -1 && key > node->right->key)

        return leftRotate(node);

    // Left Right Case

    if (balance > 1 && key > node->left->key)

    {

        node->left = leftRotate(node->left);

        return rightRotate(node);

    }

    // Right Left Case

    if (balance < -1 && key < node->right->key)

    {

        node->right = rightRotate(node->right);

        return leftRotate(node);

    }

    /* return the (unchanged) node pointer */

    return node;

}

// A utility function to print preorder

// traversal of the tree.

// The function also prints height

// of every node

void preOrder(Node *root)

{

    if(root != NULL)

    {

        cout << root->key << " ";

        preOrder(root->left);

        preOrder(root->right);

    }

}

// Driver Code

int main()

{

    Node *root = NULL;

     

    /* Constructing tree given in

    the above figure */

    root = insert(root, 10);

    root = insert(root, 20);

    root = insert(root, 30);

    root = insert(root, 40);

    root = insert(root, 50);

    root = insert(root, 25);

     

    /* The constructed AVL Tree would be

                30

            / \

            20 40

            / \ \

        10 25 50

    */

    cout << "Preorder traversal of the "

            "constructed AVL tree is \n";

    preOrder(root);

     

    return 0;

}


Related Solutions

Prerequisite Knowledge Understand binary search tree structure Understand binary search tree operations Understand binary search tree...
Prerequisite Knowledge Understand binary search tree structure Understand binary search tree operations Understand binary search tree worst case and best case time. Learning Outcomes Describe AVL tree structure Trace and implement AVL tree operations Explain and prove AVL tree performance
A binary search tree can be built with a traditional insertion method given a list of...
A binary search tree can be built with a traditional insertion method given a list of integers. Binary search trees (BSTs) are binary trees where the data is ordered such that nodes in the subtree to the left of a given node are smaller than or equal to the node, and the right subtree will contain nodes with values greater than the given node. With a built binary search tree, one can traverse the tree to print each node’s data...
A binary search tree can be built with a traditional insertion method given a list of...
A binary search tree can be built with a traditional insertion method given a list of integers. Binary search trees (BSTs) are binary trees where the data is ordered such that nodes in the subtree to the left of a given node are smaller than or equal to the node, and the right subtree will contain nodes with values greater than the given node. With a built binary search tree, one can traverse the tree to print each node’s data...
1. Modify a binary search tree implementation code (that AVL tree code depends on) to print...
1. Modify a binary search tree implementation code (that AVL tree code depends on) to print out the data value for each node it encounters in the insert operation. Remember that the module AVL tree code gets part of its functionality from the BST type, since an AVL tree is a binary search tree, but adds some additional functionality. 2. Add code to the main method to meet the following requirements: (a) Create an AVL tree to hold names stored...
(IN C) Write the code to manage a Binary Tree. Each node in the binary tree...
(IN C) Write the code to manage a Binary Tree. Each node in the binary tree includes an integer value and string. The binary tree is sorted by the integer value. The functions include: • Insert into the binary tree. This function will take in as parameters: the root of the tree, the integer value, and the string. Note that this function requires you to create the node. • Find a node by integer value: This function takes in two...
Binary Tree Create a binary search tree using the given numbers in the order they’re presented....
Binary Tree Create a binary search tree using the given numbers in the order they’re presented. State if the resulting tree is FULL and/or BALANCED. 37, 20, 18, 56, 40, 42, 12, 5, 6, 77, 20, 54
​Define a tree. Distinguish between a tree and a binary tree. Distinguish between a binary tree and a binary search tree.
Define a tree. Distinguish between a tree and a binary tree. Distinguish between a binary tree and a binary search tree.
Binary Tree Develop algorithms for performing various operations of binary tree like insertion and deletion of...
Binary Tree Develop algorithms for performing various operations of binary tree like insertion and deletion of elements, finding an element in the binary tree. Analyse time and space complexity of the designed algorithm Write C++ program to implement binary tree
Beginning with an empty binary search tree, what binary search tree is formed when you insert...
Beginning with an empty binary search tree, what binary search tree is formed when you insert the following values in the given order – consider there alphabetical position for comparison. a. W, T, N, J, E, B, A b. W, T, N, A, B, E, J c. A, B, W, J, N, T, E d. B, T, E, A, N, W, J Alphabetical positions: A-1, B-2, E-5, J-10, N-14,T-20,W-23
Lab 5: Binary Search Tree Implement operations for a Binary Search Tree class starting from the...
Lab 5: Binary Search Tree Implement operations for a Binary Search Tree class starting from the template provided under the PolyLearn assignment, using the class TreeNode that is also provided. You may (should) implement helper methods that make your code easier to write, read, and understand. You will also need to write test cases of your own as you develop the methods. You may use iterative and/or recursive functions in your implementation. The following starter files are available . •...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT