【问题标题】:Segmentation Fault in a Simple Red-Black Tree简单红黑树中的分割错误
【发布时间】:2015-12-31 05:02:45
【问题描述】:

我正在尝试用 C 语言构建一个简单的红黑树。不幸的是,我遇到了一个不知道如何修复的分段错误。我已包含下面的代码并标记到发生故障的行。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define RED 1
#define BLACK 0

typedef struct RBNode {
    char key[50];
    int color;
    struct RBNode *left;
    struct RBNode *right;
    struct RBNode *parent;
} RBNode;

typedef struct RBTree {
    struct RBNode *root;
    struct RBNode *nil;
} RBTree;

void inorderPrint(RBTree*, RBNode*);
void insertRB(RBTree*, RBNode*);
void insertRBFixup(RBTree*, RBNode*);
void leftRotate(RBTree*, RBNode*);
void rightRotate(RBTree*, RBNode*);
int count;

int main (int argc, char* argv[]) {
    RBTree *tree = malloc(sizeof(RBTree));
    tree->nil = malloc(sizeof(RBNode));
    tree->nil->color = BLACK;
    tree->root = NULL;
    tree->nil->left = tree->root;
    tree->nil->right = tree->root;
    RBNode *curr = NULL;
    curr = malloc(sizeof(RBNode));
    strcpy(curr->key, "CAT");
    insertRB(tree, curr);
    strcpy(curr->key, "HAT");
    insertRB(tree, curr);
    strcpy(curr->key, "BIT");
    insertRB(tree, curr);
    strcpy(curr->key, "CAR");
    insertRB(tree, curr);
    strcpy(curr->key, "MAP");
    insertRB(tree, curr);
    inorderPrint(tree, tree->root);
    return 1;
}

void inorderPrint(RBTree* tree, RBNode *node) {
    if ((node != NULL) && (node != tree->nil)) {
        inorderPrint(tree, node->left);
        printf("%s\n", node->key);
        inorderPrint(tree, node->right);
    }
}

void leftRotate(RBTree *tree, RBNode *x) {
    struct RBNode *y = NULL;
    y = x->right;
    x->right = y->left;
    if (y->left != tree->nil) {
        y->left->parent = x;   //Segmentation fault occurs here
    }

    y->parent = x->parent;
    if (x->parent == tree->nil) {
        tree->root = y;
    } else if (x == x->parent->left) {
        x->parent->left = y;
    } else {
        x->parent->right = y;
    }
    y->left = x;
    x->parent = y;

}

void rightRotate(RBTree *tree, RBNode *x) {
    RBNode *y = x->left;
    x->left = y->right;
    if (y->right != tree->nil) {
        y->right->parent = x;
    }
    y->parent = x->parent;
    if (x->parent == tree->nil) {
        tree->root = y;
    } else if (x == x->parent->right) {
        x->parent->right = y;
    } else {
        x->parent->left = y;
    }
    y->right = x;
    x->parent = y;
}

void insertRB(RBTree *tree, RBNode *z) {
    RBNode *y = tree->nil;
    RBNode *x = tree->root;
    while ((x != tree->nil) && (x != NULL)) {
        y = x;
        if (strcmp(z->key, x->key) < 0) {
            x = x->left;
        } else {
            x = x->right;
        }

    }
    z->parent = y;
    if (y == tree->nil) {
        tree->root = z;
    } else if (strcmp(z->key, y->key) < 0) {
        y->left = z;
    } else {
        y->right = z;
    }
    z->left = tree->nil;
    z->right = tree->nil;
    z->color = RED;
    insertRBFixup(tree, z);
}

void insertRBFixup(RBTree *tree, RBNode *z) {
    RBNode *y = NULL;
    while (z->parent->color == RED) {
        if (z->parent == z->parent->parent->left) {
            y = z->parent->parent->right;
            if (y->color == RED) {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            } else if (z == z->parent->right) {
                z = z->parent;
                leftRotate(tree, z);
            } else {
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                rightRotate(tree, z->parent->parent); 
            }

        } else {
            y = z->parent->parent->left;
            if (y->color == RED) {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            } else if (z == z->parent->left) {
                z = z->parent;
                rightRotate(tree, z);
            } else {
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                leftRotate(tree, z->parent->parent);
            }
        }
    }
    tree->root->color = BLACK;
}

我认为这可能与我在 main() 中初始化红黑树的方式有关,但我不确定,我已经尝试了许多不同的其他方式来初始化它。

你们中有人知道我哪里出错了吗?

【问题讨论】:

  • 你试过在调试器中单步调试吗?
  • 而且yy-&gt;left 都不是NULL

标签: c algorithm data-structures red-black-tree


【解决方案1】:

if (y->left != tree->nil) {
        y->left->parent = x;   //Segmentation fault occurs here
    }

y->left 可以为 NULL。

leftRotate 需要检查 NULL 指针

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 2016-03-10
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 2017-03-02
    • 2010-09-06
    • 2013-06-05
    • 2018-02-07
    相关资源
    最近更新 更多