avltree.cpp 3.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
/**
 * \file
 * \brief A simple tree implementation using nodes
 *
 * \todo update code to use C++ STL library features and OO structure
 * \warning This program is a poor implementation and does not utilize any of
 * the C++ STL features.
 */
#include <algorithm>
#include <iostream>
#include <queue>

typedef struct node {
    int data;
    int height;
    struct node *left;
    struct node *right;
} node;

/** Create and return a new Node */
node *createNode(int data) {
    node *nn = new node();
    nn->data = data;
    nn->height = 0;
    nn->left = NULL;
    nn->right = NULL;
    return nn;
}

/** Returns height of tree */
int height(node *root) {
    if (root == NULL)
        return 0;
    return 1 + std::max(height(root->left), height(root->right));
}

/** Returns difference between height of left and right subtree */
int getBalance(node *root) { return height(root->left) - height(root->right); }

/** Returns Node after Right Rotation */
node *rightRotate(node *root) {
    node *t = root->left;
    node *u = t->right;
    t->right = root;
    root->left = u;
    return t;
}

/** Returns Node after Left Rotation */
node *leftRotate(node *root) {
    node *t = root->right;
    node *u = t->left;
    t->left = root;
    root->right = u;
    return t;
}

/** Returns node with minimum value in the tree */
node *minValue(node *root) {
    if (root->left == NULL)
        return root;
    return minValue(root->left);
}

/** Balanced Insertion */
node *insert(node *root, int item) {
    node *nn = createNode(item);
    if (root == NULL)
        return nn;
    if (item < root->data)
        root->left = insert(root->left, item);
    else
        root->right = insert(root->right, item);
    int b = getBalance(root);
    if (b > 1) {
        if (getBalance(root->left) < 0)
            root->left = leftRotate(root->left);  // Left-Right Case
        return rightRotate(root);                 // Left-Left Case
    } else if (b < -1) {
        if (getBalance(root->right) > 0)
            root->right = rightRotate(root->right);  // Right-Left Case
        return leftRotate(root);                     // Right-Right Case
    }
    return root;
}

/** Balanced Deletion */
node *deleteNode(node *root, int key) {
    if (root == NULL)
        return root;
    if (key < root->data)
        root->left = deleteNode(root->left, key);
    else if (key > root->data)
        root->right = deleteNode(root->right, key);

    else {
        // Node to be deleted is leaf node or have only one Child
        if (!root->right) {
            node *temp = root->left;
            delete (root);
            root = NULL;
            return temp;
        } else if (!root->left) {
            node *temp = root->right;
            delete (root);
            root = NULL;
            return temp;
        }
        // Node to be deleted have both left and right subtrees
        node *temp = minValue(root->right);
        root->data = temp->data;
        root->right = deleteNode(root->right, temp->data);
    }
    // Balancing Tree after deletion
    return root;
}

/** LevelOrder (Breadth First Search) */
void levelOrder(node *root) {
    std::queue<node *> q;
    q.push(root);
    while (!q.empty()) {
        root = q.front();
        std::cout << root->data << " ";
        q.pop();
        if (root->left)
            q.push(root->left);
        if (root->right)
            q.push(root->right);
    }
}

/** Main function */
int main() {
    // Testing AVL Tree
    node *root = NULL;
    int i;
    for (i = 1; i <= 7; i++) root = insert(root, i);
    std::cout << "LevelOrder: ";
    levelOrder(root);
    root = deleteNode(root, 1);  // Deleting key with value 1
    std::cout << "\nLevelOrder: ";
    levelOrder(root);
    root = deleteNode(root, 4);  // Deletin key with value 4
    std::cout << "\nLevelOrder: ";
    levelOrder(root);
    return 0;
}