c - 二叉树 - 插入和删除的问题

标签 c algorithm struct tree

我需要使用方法inorder_tree_walktree_searchtree_minimumtree_successortree_inserttree_delete。当我试图编译我的程序时,我遇到了一个异常 mytree was nullptr。我可能对插入和删除方法有问题,程序的其他部分运行良好。我根据Cormen编写了这段代码。我需要任何建议,谢谢。

#include "stdafx.h"
#include <stdlib.h>

struct tree {
    int key;
    struct tree *parent, *left, *right;
    struct tree *root;
};

void inorder_tree_walk(struct tree *x) {
    if (x != NULL) {
        inorder_tree_walk(x->left);
        printf("%d ", x->key);
        inorder_tree_walk(x->right);
    }
}

struct tree *tree_search(struct tree *x, int key) {
    if (x == NULL || key == x->key)
        return x;
    if (key < (x->key)) {
        return tree_search(x->left, key);
    } else {
        return tree_search(x->right, key);
    }
}

struct tree *tree_minimum(struct tree *x) {
    while (x->left != NULL)
        x = x->left;
    return x;
}

struct tree *tree_successor(struct tree *x) {
    struct tree *y;
    if (x->right != NULL) {
        return tree_minimum(x->right);
    }
    y = x->parent;

    while (y != NULL && x == y->right) {
        x = y;
        y = y->parent;
        return y;
    }
}

struct tree *tree_insert(struct tree *mytree, int key) {
    struct tree *x = NULL;
    struct tree *z = NULL;
    struct tree *y = NULL;

    x = mytree->root;
    while (x != NULL) {
        y = x;
        if (z->key < x->key)
            x = x->left;
        else
            x = x->right;
    }
    z->parent = y;

    if (y == NULL) {
        mytree->root = z;
    } else
    if (z->key < y->key)
        y->left = z;
    else
        y->right = z;
    return 0;
}

struct tree *tree_delete(struct tree *tree, int key) {
    struct tree *z = NULL;
    struct tree *x;
    struct tree *y;

    if (z->left == NULL || z->right == NULL) {
        y = z;
    } else
        y = tree_successor(z);

    if (y->left != NULL)
        x = y->left;
    else 
        x = y->right;

    if (x != NULL)
        x->parent = y->parent;

    if (y->parent = NULL)
        tree->root = x;
    else
    if (y = y->parent->left)
        y->parent->left = x;
    else
        y->parent->right = x;

    if (y != z)
        z->key = y->key;

    return y;
}

int main() {
    tree *root = NULL;
    root = tree_insert(root, 7);
    root = tree_insert(root, 13);
    root = tree_insert(root, 8);
    root = tree_insert(root, 23);
    root = tree_insert(root, -7);
    root = tree_insert(root, 13);
    root = tree_insert(root, 31);
    root = tree_insert(root, 5);
    inorder_tree_walk(root);
    printf("\n\n");

    tree *tmp;
    tmp = tree_minimum(root);
    printf("minimum = %d\n", tmp->key);

    root = tree_delete(root, 8);
    root = tree_delete(root, -7);
    root = tree_delete(root, 31);
    inorder_tree_walk(root);
    printf("\n\n");

    tmp = tree_search(root, 13);
    if (tmp == NULL) {
        printf("not found\n");
    } else {
        printf("found\n");
    }
    getchar();
}

最佳答案

函数 tree_successor()while 循环中存在问题。您应该从 while block 中取出 return:

struct tree *tree_successor(struct tree *x) {
    struct tree *y;
    if (x->right != NULL) {
        return tree_minimum(x->right);
    }
    y = x->parent;

    while (y != NULL && x == y->right) {
        x = y;
        y = y->parent;
    }
    return y;
}

tree_insert 调用未定义的行为,因为 z 在第一个循环中取消引用时为 NULLz 应使用具有正确键值的新分配节点进行初始化。

tree_delete 有更多问题,您根本不从根节点开始遍历树。

关于c - 二叉树 - 插入和删除的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41069476/

相关文章:

java - 如何最有效地在 java 中对字符串中的数字(可以是超大的)进行排序

go - 如何访问gohtml中 slice 结构内的结构元素?

c - 数组索引之间的交换内存地址可能吗?

c - 测试损坏的列表

C++ 遍历 vector 拷贝

c++ - 通过 2d 数组 C++ 传播的最快方法

C++ 在没有指针的情况下初始化结构

tomcat - 如何将 hdiv 与多个模块集成(在同一个 tomcat 中运行)

c++ - 从 GLSL 中的数组初始化结构

c# - 自 C# 以来的 C++ 代码等效吗?