Cuente los Nodes más grandes en el árbol AVL

En este artículo veremos cómo calcular el número de elementos que son mayores que el valor dado en el árbol AVL . Ejemplos:

Input : x = 5
        Root of below AVL tree
           9
          /  \
         1    10
        /  \     \
       0    5     11
      /    /  \
     -1   2    6
Output : 4

Explanation: there are 4 values which are 
greater than 5 in AVL tree which are 6, 9, 
10 and 11.

Requisitos previos:

  1. Mantenemos un campo adicional ‘ desc ‘ para almacenar el número de Nodes descendientes de cada Node. Como en el ejemplo anterior, el Node que tiene el valor 5 tiene un valor de campo desc igual a 2. 
  2. para calcular el número de Nodes que son mayores que el valor dado, simplemente recorremos el árbol. Mientras se atraviesan pueden ocurrir tres casos:
    1. Caso: x (valor dado) es mayor que el valor del Node actual. Entonces, vamos al hijo derecho del Node actual. 
    2. Case- x es menor que el valor del Node actual. aumentamos el recuento actual por el número de sucesores del hijo derecho del Node actual y luego agregamos dos al recuento actual (uno para el Node actual y otro para el hijo derecho). En este paso primero, nos aseguramos de que el niño correcto exista o no. Luego nos movemos al hijo izquierdo del Node actual. 
    3. Case- x es igual al valor del Node actual. En este caso, agregamos el valor del campo desc del hijo derecho del Node actual al recuento actual y luego le agregamos uno (para contar el hijo derecho). También en este caso vemos que el hijo derecho existe o no. Cálculo de valores del campo desc
  • Inserción : cuando insertamos un Node, incrementamos uno al campo secundario de cada predecesor del nuevo Node. En las funciones leftRotate y rightRotate hacemos los cambios apropiados en el valor de los campos secundarios de los Nodes.
  • Eliminación : cuando eliminamos un Node, disminuimos uno de cada Node predecesor del Node eliminado. Nuevamente, en las funciones leftRotate y rightRotate hacemos los cambios apropiados en el valor de los campos secundarios de los Nodes.

Implementación:

C

// C program to find number of elements
// greater than a given value in AVL
#include <stdio.h>
#include <stdlib.h>
struct Node {
    int key;
    struct Node* left, *right;
    int height;
    int desc;
};
 
int height(struct 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;
}
 
struct Node* newNode(int key)
{
    struct Node* node = (struct Node*)
                    malloc(sizeof(struct Node));
    node->key = key;
    node->left = NULL;
    node->right = NULL;
    node->height = 1; // initially added at leaf
    node->desc = 0;
    return (node);
}
 
// A utility function to right rotate subtree
// rooted with y
struct Node* rightRotate(struct Node* y)
{
    struct Node* x = y->left;
    struct 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;
 
    // calculate the number of children of x and y
    // which are changed due to rotation.
    int val = (T2 != NULL) ? T2->desc : -1;
    y->desc = y->desc - (x->desc + 1) + (val + 1);
    x->desc = x->desc - (val + 1) + (y->desc + 1);
 
    return x;
}
 
// A utility function to left rotate subtree rooted
// with x
struct Node* leftRotate(struct Node* x)
{
    struct Node* y = x->right;
    struct 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;
 
    // calculate the number of children of x and y
    // which are changed due to rotation.
    int val = (T2 != NULL) ? T2->desc : -1;
    x->desc = x->desc - (y->desc + 1) + (val + 1);
    y->desc = y->desc - (val + 1) + (x->desc + 1);
 
    return y;
}
 
// Get Balance factor of node N
int getBalance(struct Node* N)
{
    if (N == NULL)
        return 0;
    return height(N->left) - height(N->right);
}
 
struct Node* insert(struct 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);
        node->desc++;
    }
 
    else if (key > node->key) {
        node->right = insert(node->right, key);
        node->desc++;
    }
 
    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 node becomes unbalanced, 4 cases arise
 
    // 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. */
struct Node* minValueNode(struct Node* node)
{
    struct 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.
struct Node* deleteNode(struct 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);
        root->desc = root->desc - 1;
    }
 
    // 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);
        root->desc = root->desc - 1;
    }
 
    // 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)) {
 
            struct Node* temp = root->left ?
                                root->left : root->right;
 
            // No child case
            if (temp == NULL) {
                temp = root;
                root = NULL;
                free(temp);
 
            }
            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)
            struct 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);
            root->desc = root->desc - 1;
        }
    }
 
    // 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, 4 cases arise
 
    // 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.
void preOrder(struct Node* root)
{
    if (root != NULL) {
        printf("%d ", root->key);
        preOrder(root->left);
        preOrder(root->right);
    }
}
 
// Returns count of
int CountGreater(struct Node* root, int x)
{
    int res = 0;
 
    // Search for x. While searching, keep
    // updating res if x is greater than
    // current node.
    while (root != NULL) {
 
        int desc = (root->right != NULL) ?
                root->right->desc : -1;
 
        if (root->key > x) {
            res = res + desc + 1 + 1;
            root = root->left;
        } else if (root->key < x)
            root = root->right;
        else {
            res = res + desc + 1;
            break;
        }
    }
    return res;
}
 
/* Driver program to test above function*/
int main()
{
    struct Node* root = NULL;
    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 */
 
    printf("Preorder traversal of the constructed AVL "
        "tree is \n");
    preOrder(root);
    printf("\nNumber of elements greater than 9 are %d",
        CountGreater(root, 9));
 
    root = deleteNode(root, 10);
 
    /* The AVL Tree after deletion of 10
        1
        / \
        0 9
    / / \
    -1 5 11
        / \
        2 6 */
 
    printf("\nPreorder traversal after deletion of 10 \n");
    preOrder(root);
    printf("\nNumber of elements greater than 9 are %d",
        CountGreater(root, 9));
    return 0;
}
Producción

Preorder traversal of the constructed AVL tree is 
9 1 0 -1 5 2 6 10 11 
Number of elements greater than 9 are 2
Preorder traversal after deletion of 10 
1 0 -1 9 5 2 6 11 
Number of elements greater than 9 are 1

Complejidad del tiempo: la complejidad del tiempo de la función CountGreater es O(log(n)) donde n es el número de Nodes en el árbol avl, ya que básicamente buscamos el número dado en avl que toma el tiempo O(log(n) )

Este artículo es una contribución de Ashish Sharma . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *