红黑树计划崩溃

时间:2017-02-24 15:35:37

标签: c tree crash

我正在尝试用C编写一个红黑树算法的实现,但在执行函数insert()之后,我遇到了崩溃,程序停止工作。该函数首先找到一个应该添加新值的位置,然后执行另一个名为Correct_Tree的函数,该函数负责纠正具有正确顺序和颜色的节点。

我收到的警告很少,但不知道如何修复它们,其他以相同方式构建的功能也能正常工作。

|69|warning: conflicting types for 'correct_tree' [enabled by default]|

|40|note: previous implicit declaration of 'correct_tree' was here|

相同的警告指向函数Rot_L,我不知道这个警告是否会导致我的崩溃。我会感谢每一个答案,如果您需要更多信息,请告诉我。对不起我的英语,我不是母语人士。

以下是这些功能:http://ideone.com/hsYyES 和结构看起来像这样:

struct node {
    int value;
    int key_amounts;
    char color;
    struct node *parent;
    struct node *left;
    struct node *right;
} *root;

int insert(int n, struct node *start) {
    //if node doesnt exist then add it to the tree otherwise increase amount of    keys

    //if tree is empty add root
    if (root == NULL) {
        root = (struct node*)malloc(sizeof *root);
        root->value = n;
        root->keys_amount = 0;
        root->left = NULL;
        root->right = NULL;
        root->up = NULL;
    } else
    if (search(root, n) != NULL) {
        struct node *tmp = search(root, n);
        tmp->keys_amount += 1;
        return 0;
    } else
    //if value is lower than root val then go to left son
    if (n < start->value) {
        //if left son exist then apply function insert for it
        if (start->left != NULL) {
            insert(n, start->left);
        } else {
            //if it doesnt exist then create 
            struct node *new = (struct node*)malloc(sizeof *root);
            new->value = n;
            new->keys_amount = 0;
            new->left = NULL;
            new->right = NULL;
            new->up = start;
            start->left = new;
            correct_tree(new);
        }
    } else {
        //if new value is higher than root
        //if right son exist then apply function for it
        if (start->right != NULL) {
            insert(n, start->right);
        } else {
            //if it doesnt exist create new one
            struct node *new = (struct node*)malloc(sizeof *root);
            new->value = n;
            new->keys_amount = 0;
            new->left = NULL;
            new->right = NULL;
            new->up = start;
            start->right = new;
            correct_tree(new);
        }
    }
    return 0;
}

//////////////////////////////////////////////////////////////////

void correct_tree(struct node *start) {
    struct node *tmp = (struct node*)malloc(sizeof *root);
    start->color = 'R';
    while ((start != root) && (start->up->color == 'R')) {
        if (start->up == start->up->up->left) {
            tmp = start->up->up->right; //uncle of start for tmp
            if (tmp->color == 'R') { //case 1
                start->up->color = 'B';
                tmp->color = 'B';
                start->up->up->color='R';
                start = start->up->up;
                continue;
            }
            if (start == start->up->right) { //case 2
                start = start->up;
                rot_L(start);
            }
            start->up->color = 'B'; //case3
            start->up->up->color = 'R';
            rot_R(start->up->up);
            break;
        } else { //mirror cases
            tmp = start->up->up->left;
            if (tmp->color == 'R') { //case 1
                start->up->color = 'B';
                tmp->color = 'B';
                start->up->up->color = 'R';
                start = start->up->up;
                continue;
            }
            if (start == start->up->left) { //case 2
                start = start->up;
                rot_R(start);
            }
            start->up->color = 'B'; //case3
            start->up->up->color = 'R';
            rot_L(start->up->up);
            break;
        }
    }
    root->color = 'B';
}

//////////////////////////////////////////////////////////////

void rot_L(struct node *start) {
    struct node *tmp = (struct node*)malloc(sizeof *root);
    struct node *tmp2 = (struct node*)malloc(sizeof *root);
    tmp = start->right;
    if (tmp != NULL) {
        tmp2 = start->up;
        start->right = tmp->left;
        if (start->right != NULL)
            start->right->up = start;
        tmp->left = start;
        tmp->up = tmp2;
        start->up = tmp;
        if (tmp2 != NULL) {
            if (tmp2->left == start)
                tmp2->left = tmp;
            else
                tmp2->right = tmp;
        } else
            root = tmp;
    }
}

1 个答案:

答案 0 :(得分:0)

编译器发出的警告告诉您在调用之前没有声明或定义correct_node。编译器从调用中推断出的原型是int correct_tree(struct node *start);,这与它稍后遇到的实际定义不兼容:void correct_tree(struct node *start)rot_L()的问题相同。在调用它们之前声明所有函数。

函数correct_node必然会失败,因为您取消引用up链接,而不先检查它们是否为NULL。例如,当您第一次致电correct_node on theorchild of the root`节点时,您有:

start->color = 'R';
while ((start != root) && (start->up->color == 'R')) {
    if (start->up == start->up->up->left) {

您没有初始化color分配的root节点的malloc()root->color可能等于'R'的可能性很小,这会导致start->up->up->left具有未定义的行为,start->up->upNULL

另一个问题是:

struct node *tmp = (struct node*)malloc(sizeof *root);

从不使用为tmp分配的对象,从不释放,并且在循环中覆盖tmp。这是一个明显的内存泄漏案例。

rot_L tmptmp2中,同样的问题出现了两次。