• 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;
    }
    
  • 相关阅读:
    分享:图书馆常用开源软件
    一个 Python 程序每一行的内存占用分析 杨超(星辰海 | 真人图书馆·Python 程序员) 42qu.com
    分享:使用 const_cast<> 改变map中 key 的值
    Examples · Remarkerbe
    内联函数
    什么值得买 » 体感神器?Leap Motion 运动控制器(Kinect的200倍精确度) $69.99预定(直邮中国运费$14.99)Leap Motion外设产品,新鲜物,海淘特价
    HiveClient
    sentry : 前端&后端 的 错误信息统计 张沈鹏(42qu.com·创始人&程序员) 42qu.com
    fabric
    fabric调用代码分析
  • 原文地址:https://www.cnblogs.com/zhayujie/p/12941563.html
Copyright © 2020-2023  润新知