系列文章记录重回开发之路----3.二叉树与红黑树

二叉树与红黑树

二叉排序树

二叉排序树性质:
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。

二叉树,实现了 插入、删除功能。删除功能代码感觉韧性不够。仍然缺少整体构建思维,比如,在写该功能模块之前,应分析该删除的节点的子节点分类情形:

  1. 0个子节点、
  2. 1个子节点
  3. 2个子节点。
    按照这个思路写代码,会比较顺。
#include <stdlib.h>
#include <stdio.h>


#define KEY_VALUE int

#define BSTREE_ENTRY(name ,type)    \
    struct name{                    \
        struct type *left;          \
        struct type *right;         \
    }

//二叉树节点
struct bstree_node {
    KEY_VALUE  data;
    BSTREE_ENTRY(,bstree_node)bst;
};

//二叉树根节点
struct bstree {
    struct bstree_node *root;
};

//创造节点
struct bstree_node * _bstree_create_node(KEY_VALUE value)
{
    struct bstree_node *node = (struct bstree_node *)malloc(sizeof(struct bstree_node));
    if (node == NULL) {
        printf("malloc error!\n");
        return NULL;
    }
    node->data = value;
    node->bst.left = node->bst.right = NULL;
    return node;
}

//插入节点
int bstree_insert(struct bstree *T, KEY_VALUE data)
{
    if (T->root == NULL) {
        T->root = _bstree_create_node(data);
        return 0;
    }

    struct bstree_node *temp = T->root;
    struct bstree_node *node = T->root;

    while (temp != NULL) {
        node = temp;
        if (data > temp->data) {
            temp = temp->bst.right;
        } else if (data < temp->data) {
            temp = temp->bst.left;
        } else {
            printf("data already exist!\n");
            return -1;
        }
    }

    if (data > node->data) {
        node->bst.right = _bstree_create_node(data);
    } else {
        node->bst.left = _bstree_create_node(data);
    }

    return 0;
}

void bstree_successor(struct bstree *T, struct bstree_node *x) {
    struct bstree_node *node = x;
    struct bstree_node *temp = x;
    while (temp->bst.left != NULL) {
        node = temp;
        temp = temp->bst.left;
    }
    T->root->data = temp->data;
    if (temp == T->root->bst.right) {
        T->root->bst.right = temp->bst.right;
        free(temp);
        return;
    }
    node->bst.left = NULL;
    free(temp);
}
void bstree_successor_node(struct bstree_node *T, struct bstree_node *x)
{
    struct bstree_node *node = T;
    struct bstree_node *temp = x;
    while (temp->bst.left != NULL) {
        node = temp;
        temp = temp->bst.left;
    }

    T->data = temp->data;
    if (temp == T->bst.right) {
        free(T->bst.right);
        T->bst.right = NULL;
        return;
    }
    node->bst.left = NULL;
    free(temp);

}
//删除节点
/*
    1. 删除的是根节点
    2. 删除的不是根节点

    采用交换的方法 将待“删除”节点的后继的值放入“删除“节点中,然后删除后继节点。

*/
int bstree_delete(struct bstree *T, KEY_VALUE data)
{
    struct bstree_node *temp = T->root;
    struct bstree_node *node = T->root;
    while(temp != NULL) {
        if (data == temp->data) {
           if(temp == T->root){
                if (temp->bst.right == NULL) {
                    T->root = temp->bst.left;
                    free(temp);
                    return 0;
                } else {
                    bstree_successor(T, temp->bst.right);
                }
           } else {
                if (temp->bst.right == NULL) {
                    if (temp == node->bst.right) {
                        node->bst.right = temp->bst.left;
                        free(temp);
                    } else {
                        node->bst.left = temp->bst.left;
                        free(temp);
                    }
                } else {
                        bstree_successor_node(temp, temp->bst.right);
                }
           }
           return 0;
        } else if (data > temp->data) {
            node = temp;
            temp = temp->bst.right;
        } else {
            node = temp;
            temp = temp->bst.left;
        }
    }
    printf("no node!\n");
    return -1;
}
void bstree_traversal(struct bstree_node *node) {
    if (node ==NULL) return ;
    bstree_traversal(node->bst.left);
    printf("%4d", node->data);
    bstree_traversal(node->bst.right);
}
int main(int argc, char* argv[])
{
    struct bstree T;
    int buf[20] = {32,52,13,53,23, 26,77,46,37,98, 20,13,17,48,10, 19,9,24,14,16};
    int i;
    for(i=0; i<20; i++){
       bstree_insert(&T, buf[i]);
    }
    bstree_traversal(T.root);
     putchar('\n');
}

红黑树,还没有搞明白,待搞明白后,在编写代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值