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;
}

你可能感兴趣的:(C/C++,算法)