简体   繁体   English

简单红黑树中的分割错误

[英]Segmentation Fault in a Simple Red-Black Tree

I'm trying to build a simple red-black tree in C. Unfortunately, I have encountered a segmentation fault that I'm not sure how to fix.我正在尝试用 C 构建一个简单的红黑树。不幸的是,我遇到了一个我不知道如何修复的分段错误。 I've included the code below and marked to line where the fault is occurring.我已经包含了下面的代码并标记到发生故障的行。

#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;
}

I think it might have something to do with how I initialized the red-black tree in main(), but I'm not sure and I've tried many different other ways to initialize it.我认为这可能与我在 main() 中初始化红黑树的方式有关,但我不确定,我已经尝试了许多不同的其他方法来初始化它。

Do any of you guys know where I'm going wrong?你们中有人知道我哪里错了吗?

In

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

y->left can be NULL. y->left 可以为 NULL。

leftRotate need to check for NULL pointers leftRotate 需要检查 NULL 指针

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM