如何使用C语言实现平衡二叉树数据结构算法

使用C语言实现平衡二叉树数据结构算法可以分为以下几个步骤:

第一步:了解平衡二叉树

平衡二叉树是一种二叉搜索树,它具有以下特点:

  • 高度平衡:每个节点的左右子树的高度差不能超过1。
  • 有序性:对于任意一个节点,它的左子树中的所有节点都小于它,它的右子树中的所有节点都大于它。

平衡二叉树的优点在于它的查找、插入和删除操作都可以在O(log n)的时间内完成,比较快速。常见的平衡二叉树有红黑树和AVL树。

第二步:实现数据结构

要实现平衡二叉树,需要先定义数据结构。一个平衡二叉树节点应该包含以下信息:

  • 节点值 val
  • 左右子树指针 left 和 right
  • 节点高度 height

定义节点结构体:

typedef struct node {
    int val;
    struct node *left;
    struct node *right;
    int height;
} Node;

然后定义插入、删除等操作。以下是AVL树的实现代码。

插入操作

首先,需要定义计算节点高度的函数:

int height(Node *node) {
    if (!node)
        return 0;
    return node->height;
}

然后,可以写出插入节点的函数。当插入一个节点时,需要更新整棵树的高度和平衡因子。若某个节点的平衡因子超过 1 或小于 -1,则可能不在平衡状态,需要进行旋转操作。

int balanceFactor(Node *node) {
    return height(node->left) - height(node->right);
}

Node* rightRotate(Node *y) {
    Node *x = y->left;
    Node *T2 = x->right;

    x->right = y;
    y->left = T2;

    y->height = max(height(y->left), height(y->right)) + 1;
    x->height = max(height(x->left), height(x->right)) + 1;

    return x;
}

Node* leftRotate(Node *x) {
    Node *y = x->right;
    Node *T2 = y->left;

    y->left = x;
    x->right = T2;

    x->height = max(height(x->left), height(x->right)) + 1;
    y->height = max(height(y->left), height(y->right)) + 1;

    return y;
}

Node* insert(Node *node, int val) {
    if (!node) {
        Node *new = (Node *)malloc(sizeof(Node));
        new->val = val;
        new->left = NULL;
        new->right = NULL;
        new->height = 1;
        return new;
    }

    if (val < node->val) {
        node->left = insert(node->left, val);
    } else if (val > node->val) {
        node->right = insert(node->right, val);
    } else {
        return node;
    }

    node->height = max(height(node->left), height(node->right)) + 1;

    int bf = balanceFactor(node);

    if (bf > 1 && val < node->left->val) {
        return rightRotate(node);
    }

    if (bf < -1 && val > node->right->val) {
        return leftRotate(node);
    }

    if (bf > 1 && val > node->left->val) {
        node->left = leftRotate(node->left);
        return rightRotate(node);
    }

    if (bf < -1 && val < node->right->val) {
        node->right = rightRotate(node->right);
        return leftRotate(node);
    }

    return node;
}

删除操作

删除节点时,需要在树中找到对应的节点,然后对其进行删除操作。当一个或多个节点被删除时,可能会破坏树的平衡状态,需要进行平衡操作来保证树的平衡性。

Node* minValueNode(Node *node) {
    Node *cur = node;
    while (cur->left) {
        cur = cur->left;
    }
    return cur;
}

Node* deleteNode(Node *node, int val) {
    if (!node) {
        return node;
    }

    if (val < node->val) {
        node->left = deleteNode(node->left, val);
    } else if (val > node->val) {
        node->right = deleteNode(node->right, val);
    } else {
        if (!node->left || !node->right) {
            Node *temp = node->left ? node->left : node->right;

            if (!temp) {
                temp = node;
                node = NULL;
            } else {
                *node = *temp;
            }

            free(temp);
        } else {
            Node *temp = minValueNode(node->right);
            node->val = temp->val;
            node->right = deleteNode(node->right, temp->val);
        }
    }

    if (!node) {
        return node;
    }

    node->height = max(height(node->left), height(node->right)) + 1;

    int bf = balanceFactor(node);

    if (bf > 1 && balanceFactor(node->left) >= 0) {
        return rightRotate(node);
    }

    if (bf > 1 && balanceFactor(node->left) < 0) {
        node->left = leftRotate(node->left);
        return rightRotate(node);
    }

    if (bf < -1 && balanceFactor(node->right) <= 0) {
        return leftRotate(node);
    }

    if (bf < -1 && balanceFactor(node->right) > 0) {
        node->right = rightRotate(node->right);
        return leftRotate(node);
    }

    return node;
}

第三步:测试代码

为了验证实现是否正确,需要编写测试代码。以下是两个测试样例:

插入元素

int main() {
    Node *root = NULL;

    root = insert(root, 10);
    root = insert(root, 20);
    root = insert(root, 30);
    root = insert(root, 40);
    root = insert(root, 50);
    root = insert(root, 25);

    printf("Inorder traversal of the constructed AVL tree is: \n");
    inorder(root);

    root = deleteNode(root, 50);

    printf("\nInorder traversal of the AVL tree after deletion of 50 is: \n");
    inorder(root);

    return 0;
}

输出:

Inorder traversal of the constructed AVL tree is:
10 20 25 30 40 50
Inorder traversal of the AVL tree after deletion of 50 is:
10 20 25 30 40

删除元素

int main() {
    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);

    /*
                9
               / \
              1  10
            /  \   \
           0    5   11
           /    / \
         -1    2   6
    */

    printf("Preorder traversal of the constructed AVL tree is \n");
    preorder(root);

    root = deleteNode(root, 10);

    /*
               1
              / \
             0   9
            /   / \
          -1   5   11
              / \
             2   6
    */

    printf("\nPreorder traversal after deletion of 10 \n");
    preorder(root);

    return 0;
}

输出:

Preorder traversal of the constructed AVL tree is
1 0 -1 9 5 2 6 10 11
Preorder traversal after deletion of 10
1 0 -1 5 2 6 9 11

到此为止,就完成了使用C语言实现平衡二叉树数据结构算法的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:如何使用C语言实现平衡二叉树数据结构算法 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C++ 数据结构之kmp算法中的求Next()函数的算法

    C++ 数据结构之kmp算法中的求Next()函数的算法 什么是KMP算法和Next()函数 KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,能够解决的问题是,在一个文本串S中查找一个模式串P是否出现并且返回第一次出现的位置。而Next()函数则是在KMP算法中使用的一个关键的子函数,用于计算模式串P中每个前缀的最长相同真前缀和后…

    数据结构 2023年5月17日
    00
  • java实现队列数据结构代码详解

    Java实现队列数据结构代码详解 1. 队列数据结构简介 队列(Queue)是一种先进先出(FIFO)的数据结构,支持在一端插入元素,在另一端删除元素并返回删除的元素。其操作包括入队(enqueue)和出队(dequeue)。 2. 队列实现方法 队列可以通过数组或链表来实现。其中,数组实现的队列称为顺序队列,链表实现的队列称为链式队列。 2.1 顺序队列 …

    数据结构 2023年5月17日
    00
  • Redis的六种底层数据结构(小结)

    Redis的六种底层数据结构(小结) 简介 Redis是一种基于内存的高效键值存储数据库,它支持六种不同的数据结构来存储数据。这些结构旨在提供高速、灵活和功能强大的一系列功能。在学习Redis时,了解这些数据结构可以帮助您更好地使用Redis并更好地解决您的问题。 Redis的六种底层数据结构 Redis支持以下六种不同的数据结构: String (字符串)…

    数据结构 2023年5月17日
    00
  • JoshChen_php新手进阶高手不可或缺的规范介绍

    JoshChen_php新手进阶高手不可或缺的规范介绍 作为一名PHP程序员,熟练掌握编程语言的同时,规范的代码风格也是不可或缺的。本文将介绍一些PHP规范的相关内容,帮助PHP新手进阶为高手。 1. 代码风格规范 1.1. 缩进 在编写代码时,缩进是非常重要的。按照规范,我们应该在每个缩进级别使用4个空格。 1.2. 命名规范 在PHP中,我们应该遵循以下…

    数据结构 2023年5月17日
    00
  • go语言数据结构之前缀树Trie

    前缀树Trie 前缀树Trie是一种树形数据结构,被用于快速查找内存中的字符串数据。它非常适合存储大量的字符串,并且能够非常快速的查找以一个指定的字符串前缀开头的全部字符串。 相关术语 在学习前缀树Trie之前,需要掌握一下相关术语: 根节点:Trie树的根节点,代表空字符串。 边:连接两个节点的线,代表一个字符。 节点:表示一个字符串,可能是某个字符串的结…

    数据结构 2023年5月17日
    00
  • 「线段树」!(简单)的线段树

    本题为3月20日23上半学期集训每日一题中B题的题解 题面 题目描述 给你一个序列 \(A[1],A[2],…,A[n]\) .( \(|A[i]| \leq 15007, 1 \leq N \leq 50,000\) ). M( \(1 \leq M \leq 500,000\) ) 次询问,每次询问 \(Query(x, y) = Max{A[i] …

    算法与数据结构 2023年4月18日
    00
  • 详解python数据结构之队列Queue

    详解Python数据结构之队列 (Queue) 在计算机科学中,队列(Queue)是一种数据结构,可以用于按顺序存储和访问元素。该数据结构遵循先进先出(FIFO)原则,人们可以从队列的前面插入元素,从队列的后面删除元素。Python内置了队列模块(queue),这个模块实现了多线程安全队列、同步机制及相关数据结构。Queue模块提供了三种队列类型: FIFO…

    数据结构 2023年5月17日
    00
  • Python中的函数式编程:不可变的数据结构

    Python是一门支持函数式编程的语言。相比于传统的命令式编程,函数式编程更加强调数据的不可变性。本文将介绍如何在Python中使用不可变的数据结构实现函数式编程。 什么是不可变的数据结构? 不可变数据结构是指一旦创建就无法改变的数据结构。在Python中,元组(tuple)是一个典型的不可变数据结构。以下是一个创建元组的示例代码: a_tuple = (1…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部