AVL树C语言实现

参考: https://www.cnblogs.com/skywang12345/p/3576969.html

AVLTree.h
#ifndef _AVL_TREE_H_
#define _AVL_TREE_H_

typedef int Type;

struct AVLTreeNode {
    Type key;
    int height;
    struct AVLTreeNode *left;
    struct AVLTreeNode *right;
};

// 获取AVL树的高度
int avltree_height(struct AVLTreeNode *tree);

// 前序遍历AVL树
void avltree_preorder(struct AVLTreeNode *tree);

// 中序遍历AVL树
void avltree_inorder(struct AVLTreeNode *tree);

// 后序遍历AVL树
void avltree_postorder(struct AVLTreeNode *tree);

// (递归实现)查找AVL树键值为key的节点
struct AVLTreeNode* avltree_search(struct AVLTreeNode *tree, Type key);

// (非递归实现)查找AVL树键值为key的节点
struct AVLTreeNode* avltree_iterative_search(struct AVLTreeNode *tree, Type key);

// 查找最小节点, 也就是AVL树最左节点
struct AVLTreeNode* avltree_min(struct AVLTreeNode *tree);

// 查找最大节点, 也就是AVL树最右节点
struct AVLTreeNode* avltree_max(struct AVLTreeNode *tree);

// 插入节点 返回新的根节点, 因为插入的节点有可能替换根节点
struct AVLTreeNode* avltree_insert(struct AVLTreeNode *tree, Type key);

// 删除节点 返回新的根节点, 因为删除的节点可能就是根节点
struct AVLTreeNode* avltree_delete(struct AVLTreeNode *tree, Type key);

// 销毁AVL树
void avltree_destroy(struct AVLTreeNode *tree);


#endif
AVLTree.c
#include "AVLTree.h"
#include <stdio.h>
#include <stdlib.h>

#define HEIGHT(p)   ((p==NULL) ? 0 : (((struct AVLTreeNode*)(p))->height))
#define MAX(a, b)   ((a) > (b) ? (a) : (b))

// 获取AVL树的高度
int avltree_height(struct AVLTreeNode *tree)
{
    return HEIGHT(tree);
}

// 前序遍历AVL树
void avltree_preorder(struct AVLTreeNode *tree)
{
    if (tree) {
        printf("%d ", tree->key);
        avltree_preorder(tree->left);
        avltree_preorder(tree->right);
    }
}

// 中序遍历AVL树
void avltree_inorder(struct AVLTreeNode *tree)
{
    if (tree) {
        avltree_inorder(tree->left);
        printf("%d ", tree->key);
        avltree_inorder(tree->right);
    }
}

// 后序遍历AVL树
void avltree_postorder(struct AVLTreeNode *tree)
{
    if (tree) {
        avltree_postorder(tree->left);
        avltree_postorder(tree->right);
        printf("%d ", tree->key);
    }
}

// (递归实现)查找AVL树键值为key的节点
struct AVLTreeNode* avltree_search(struct AVLTreeNode *tree, Type key)
{
    if (tree==NULL || key==tree->key) {
        return tree;
    }

    if (tree->key > key)
        return avltree_search(tree->left, key);
    else
        return avltree_search(tree->right, key);
}

// (非递归实现)查找AVL树键值为key的节点
struct AVLTreeNode* avltree_iterative_search(struct AVLTreeNode *tree, Type key)
{
    while ((tree != NULL) && (tree->key != key)) {
        if (key < tree->key)
            tree = tree->left;
        else
            tree = tree->right;
    }

    return tree;
}

// 查找最小节点, 也就是AVL树最左节点
struct AVLTreeNode* avltree_min(struct AVLTreeNode *tree)
{
    if (tree == NULL)
        return tree;

    while (tree->left != NULL)
        tree = tree->left;

    return tree;
}

// 查找最大节点, 也就是AVL树最右节点
struct AVLTreeNode* avltree_max(struct AVLTreeNode *tree)
{
    if (tree == NULL)
        return tree;

    while (tree->right != NULL)
        tree = tree->right;

    return tree;
}

// LL: 左左对应的情况 左单旋转, 返回旋转后的根节点
static struct AVLTreeNode* LL_Rotation(struct AVLTreeNode *tree)
{
    struct AVLTreeNode *k1;

    k1 = tree->left;
    tree->left = k1->right;
    k1->right = tree;

    tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
    k1->height = MAX(HEIGHT(k1->left), tree->height) + 1;

    return k1;
}

// RR: 右右对应的情况 右单旋转, 返回旋转后的节点
static struct AVLTreeNode* RR_Rotation(struct AVLTreeNode *tree)
{
    struct AVLTreeNode *k1;

    k1 = tree->right;
    tree->right = k1->left;
    k1->left = tree;

    tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
    k1->height = MAX(HEIGHT(k1->left), tree->height) + 1;

    return k1;
}

// LR: 左右对应的情况 左双旋转, 返回旋转后的节点
static struct AVLTreeNode* LR_Rotation(struct AVLTreeNode *tree)
{
    // 对tree的左子树进行RR旋转
    tree->left = RR_Rotation(tree->left);

    // 对tree进行LL旋转
    return LL_Rotation(tree);
}

// RL: 右左对应的情况 右双旋转, 返回旋转后的节点
static struct AVLTreeNode* RL_Rotation(struct AVLTreeNode *tree)
{
    // 对tree的右子树进行LL旋转
    tree->right = LL_Rotation(tree->right);

    // 对tree进行RR旋转
    return RR_Rotation(tree);
}

// 创建一个AVL树的节点
static struct AVLTreeNode* avltree_create_node(Type key, struct AVLTreeNode *left, struct AVLTreeNode *right)
{
    struct AVLTreeNode *p = NULL;

    p = (struct AVLTreeNode*)malloc(sizeof(struct AVLTreeNode));
    if (p == NULL)
        return NULL;

    p->height = 0;
    p->key = key;
    p->left = left;
    p->right = right;

    return p;
}


// 插入节点 返回新的根节点, 因为插入的节点有可能替换根节点
struct AVLTreeNode* avltree_insert(struct AVLTreeNode *tree, Type key)
{
    if (tree == NULL) {
        tree = avltree_create_node(key, NULL, NULL);
        if (tree == NULL) {
            printf("avltree_create_node failed. \r\n");
            return NULL;
        }
    } else if (key < tree->key) {
        // key 小于 root->key 应该插入到左子树中去
        tree->left = avltree_insert(tree->left, key);
        // 插入后, 需要判断平衡 进行调整
        if ((HEIGHT(tree->left) - HEIGHT(tree->right)) == 2) {
            if (key < tree->left->key) {
                // 是由于插入到LL导致的失衡, LL旋转调整
                tree = LL_Rotation(tree);
            } else {
                // 是由于插入到LR导致的失衡, LR旋转调整
                tree = LR_Rotation(tree);
            }
        }
    } else if (key > tree->key) {
        // key 大于 root->key 应该插入到右子树中去
        tree->right = avltree_insert(tree->right, key);
        if ((HEIGHT(tree->right) - HEIGHT(tree->left)) == 2) {
            if (key > tree->right->key) {
                // 是由于插入到RR导致的失衡, RR旋转调整
                tree = RR_Rotation(tree);
            } else {
                // 是由于插入到RL导致的失衡, RL旋转调整
                tree = RL_Rotation(tree);
            }
        }
    } else {
        printf("avltree_insert failed, the key has existed. \r\n");
    }

    tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;    // 更新一下tree的高度数值

    return tree;
}

static struct AVLTreeNode* __avltree_delete(struct AVLTreeNode *tree, struct AVLTreeNode *node)
{
    struct AVLTreeNode *t = NULL;
    if (tree==NULL || node==NULL)
        return NULL;

    if (node->key < tree->key) {
        // 要删除的节点在tree的左子树中
        tree->left = __avltree_delete(tree->left, node);
        // 删除该节点以后, 看一下tree是否失衡了, 需要调整
        if ((HEIGHT(tree->right) - HEIGHT(tree->left)) == 2) {
            t = tree->right;
            if (t->right > t->left) {
                // RR 
                tree = RR_Rotation(tree);
            } else {
                // RL
                tree = RL_Rotation(tree);
            }
        }
    } else if (node->key > tree->key) {
        // 要删除的节点在tree的右子树中
        tree->right = __avltree_delete(tree->right, node);
        if ((HEIGHT(tree->left) - HEIGHT(tree->right)) == 2) {
            t = tree->left;
            if (t->left > t->right) {
                // LL
                tree = LL_Rotation(tree);
            } else {
                // LR
                tree = LR_Rotation(tree);
            }
        }
    } else {
        // tree正是要删除的节点
        if (tree->left==NULL) {
            // tree的左子树为空 删除tree节点 返回tree的右子树
            t = tree;
            tree = tree->right;
            free(t);
        } else if (tree->right==NULL) {
            // tree的右子树为空 删除tree节点 返回tree的左子树
            t = tree;
            tree = tree->left;
            free(t);
        } else {
            // tree的左右子树都不为空
            if (HEIGHT(tree->left) > HEIGHT(tree->right)) {
                // tree的左子树比右子树高, 找出左子树最大节点, 将该最大节点赋值给tree, 删除该最大节点
                t = avltree_max(tree->left);
                tree->key = t->key;
                tree->left = __avltree_delete(tree->left, t);   // __avltree_delete 返回的肯定是AVL树
            } else {
                // tree的左子树不必右子树高, 找出右子树最小节点, 将该最小节点赋值给tree, 删除该最小节点
                t = avltree_min(tree->right);
                tree->key = t->key;
                tree->right = __avltree_delete(tree->right, t); // // __avltree_delete 返回的肯定是AVL树
            }
        }
    }

    return tree;
}

// 删除节点 返回新的根节点, 因为删除的节点可能就是根节点
struct AVLTreeNode* avltree_delete(struct AVLTreeNode *tree, Type key)
{
    struct AVLTreeNode *node = NULL;

    #if 1       // 采用递归查找
    node = avltree_search(tree, key);
    #else       // 采用非递归查找
    node = avltree_iterative_search(tree, key);
    #endif
    if (node) {
        tree = __avltree_delete(tree, node);
    }

    return tree;        // 返回删除该节点以后的tree树根节点
}

// 销毁AVL树
void avltree_destroy(struct AVLTreeNode *tree)
{
    if (tree == NULL)
        return;

    if (tree->left)
        avltree_destroy(tree->left);

    if (tree->right)
        avltree_destroy(tree->right);

    free(tree);
}
main.c
#include <stdio.h>
#include "AVLTree.h"

static int arr[] = {3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9};
#define TBL_SIZE(a) ((sizeof(a))/(sizeof(a[0])))

int main(int argc, char* argv[])
{
    int i = 0, len = 0;
    struct AVLTreeNode *root = NULL;

    printf("== 高度: %d \r\n", avltree_height(root));
    printf("== 依次添加: ");
    len = TBL_SIZE(arr);
    for (i = 0; i < len; i++) {
        printf("%d ", arr[i]);
        root = avltree_insert(root, arr[i]);
    }
    printf("\r\n");

    printf("== 前序遍历: ");
    avltree_preorder(root);
    printf("\r\n");

    printf("== 中序遍历: ");
    avltree_inorder(root);
    printf("\r\n");

    printf("== 后序遍历: ");
    avltree_postorder(root);
    printf("\r\n");

    printf("== 高度: %d \r\n", avltree_height(root));
    printf("== 最小值: %d \r\n", avltree_min(root)->key);
    printf("== 最大值: %d \r\n", avltree_max(root)->key);

    return 0;
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值