zoukankan      html  css  js  c++  java
  • AVL树的创建--C语言实现

    AVL树是一种自平衡(Self-balancing)二叉查找树(Binary Search Tree),要求任何一个节点的左子树和右子树的高度之差不能超过1。

    AVL树的插入操作首先会按照普通二叉查找树的插入操作进行,不同的是在成功插入一个节点后会向上进行回溯,判断路径中的每一个节点左子树和右子树高度之差,如果相差大于1,则进行旋转操作使得树重新达到平衡状态,旋转的本质其实是为当前不平衡的子树选择一个新的根节点,以降低两侧的高度差。

    这里以root表示不平衡节点(左右子树高度差大于1),旋转操作可分为以下四种:

    • 右旋转:当加入的节点在root的左子节点的左子树中(LL),以root为轴进行一次右旋转。
    • 左旋转:当加入的节点在root的右子节点的右子树中(RR),以root为轴进行一次左旋转。
    • 左右旋转:当加入的节点在root的左子节点的右子树中(LR),先以root的左子节点为轴进行一次左旋转,再以root为轴进行一次右旋转。
    • 右左旋转:当加入的节点在root的右子节点的左子树中(RL),先以root的右子节点为轴进行一次右旋转,再以root为轴进行一次左旋转。

    代码如下:

    #include <cstdio>
    #include <cstdlib>
    #define max(x, y) (((x) > (y)) ? (x) : (y))
    typedef struct tnode
    {
        int val;
        struct tnode * left;
        struct tnode * right;
    } node;
    
    //LL:右旋转
    node * rotate_right(node * root) {
        node * lnode = root->left;
        root->left = lnode->right;
        lnode->right = root;
        return lnode;
    }
    
    //RR:左旋转
    node * rotate_left(node * root) {
        node * rnode = root->right;
        root->right = rnode->left;
        rnode->left = root;
        return rnode;
    }
    
    //LR:先左旋转,再右旋转
    node * rotate_left_right(node * root) {
        root->left = rotate_left(root->left);
        return rotate_right(root);
    }
    
    //RL:先右旋转,再左旋转
    node * rotate_right_left(node * root) {
        root->right = rotate_right(root->right);
        return rotate_left(root);
    }
    
    //递归求得以root为根节点的树的高度
    int get_height(node * root) {
        if (root == NULL)   return 0;
        return max(get_height(root->left), get_height(root->right)) + 1;
    }
    
    //在以root为根节点的树中插入值为val的节点
    node * insert(node * root, int val) {
        if (root == NULL) {
            root = (node *) malloc(sizeof(node));
            root->val = val;
            root->left = NULL;
            root->right = NULL;
        } else if (val < root->val) {
            root->left = insert(root->left, val);
            if (get_height(root->left) - get_height(root->right) == 2) {
                if (val < root->left->val)      root = rotate_right(root);
                else                            root = rotate_left_right(root);
            }
        } else {
            root->right = insert(root->right, val);
            if (get_height(root->right) - get_height(root->left) == 2) {
                if (val > root->right->val)     root = rotate_left(root);
                else                            root = rotate_right_left(root);
            }
        }
    
        return root;
    }
    
    int main(void) {
        int n, val;
        node * root = NULL;
    
        scanf("%d", &n);
        for (int i = 0; i < n; i++) {
            scanf("%d", &val);
            root = insert(root, val);
        }
    
        return 0;
    }
    
  • 相关阅读:
    用于主题检测的临时日志(594fb726-af0b-400d-b647-8b1d1b477d72
    返璞归真vc++之字符类型
    DIV居中
    程序员职业生涯
    枚举进程句柄
    不使用mutex设计模式解决并发访问cache
    服务器权重分配算法
    xmemecached中的一致性hash算法
    安卓课堂练习
    pythonPTA---分支循环与集合7-1 jmu-python-韩信点兵 (20分) 7-2 打印数字矩形 (10分) 7-3 成绩统计 (10分) 7-4 找列表中最大元素的下标 7-5 删除列表中的重复值
  • 原文地址:https://www.cnblogs.com/zhayujie/p/12941563.html
Copyright © 2011-2022 走看看