C意外的分段错误

时间:2017-12-05 04:40:08

标签: c segmentation-fault

我正在尝试在C中实现avl树。以下是我的代码的一部分。 struct Node包含结构变量,包括整数键,高度和该节点的父,左和右子节点的3个点。

在下面的代码中,我插入" 8"与" 2,6"进入一棵树。我打印出节点右边孩子的钥匙(即6)。但是,当我将指针传递给insertright()函数并立即打印出正确的孩子时,它不是6而是一个神秘的数字。因为我需要找到#34; 6"的正确孩子,它会在下一步给我一个分段错误。

最奇怪的是我在Macbook上使用gcc编译并运行它。但是当我运行一些在线编译器(即repl.it)时,它适用于这种情况(当添加更多元素时,分段错误仍然存​​在)。

谢谢!

//*tree is the root node of the tree
void insert(struct Node *tree, int element)
{
    printf("tree rightchild node: %d, element: %d\n", tree->rightchild->key, element);
    (element < (tree->key))? insertleft(tree, element): insertright(tree, element);
}

int insertright(struct Node *self, int element){
printf("right insertion\n");
printf("rightchild node: %d\n", self->rightchild->key);

if (self->rightchild != &emptynode)
{
    //printf("self node: %d\n", self->rightchild->key);
    insert(self->rightchild, element);
}

// Output
tree rightchild node: 6, element: 8
right insertion
rightchild node: 1372646176

原始代码如下:

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

struct Node {
    int key, height;
    struct Node *parent, *leftchild, *rightchild;
};

struct Node emptynode = {.key = 0, .height = 0, .parent = NULL, .leftchild = NULL, .rightchild = NULL};

int max(int a, int b);
void insert(struct Node *node, int element);
int insertleft(struct Node *self, int element);
int insertright(struct Node *self, int element);
void rotate(struct Node *self, int flag);
void leftRotation(struct Node *self);
void rightRotation(struct Node *self);
int query(struct Node *self, int value);

int main()
{
    // int test[] = {2,6,8,4,10,20,12,14,16,18,30,40,50,22,24,28,26,48,46,44,42,34,32,36,38,100,60,70,80,88,76,62};
    int test[] = {2,6,8};
    int n = sizeof(test)/sizeof(int);
    struct Node root = {.key = test[0], .height = 1, .parent = &emptynode, .leftchild = &emptynode, .rightchild = &emptynode};
    struct Node *tree = &root;

    for(int i = 1; i<=n-1; i++)
    {
        printf("elment inserted: %d\n", test[i]);
        printf("before insertion: %d\n", tree->rightchild->key);
        insert(tree, test[i]);
        if (tree->parent != &emptynode)
            tree = tree->parent;
        printf("root key: %d\n", tree->key);
    }

    return 0;
}

int max(int a, int b)
{
    return (a>b)? a: b;
}

void insert(struct Node *tree, int element)
{
    printf("tree rightchild node: %d, element: %d\n", tree->rightchild->key, element);
    //printf("self node: %d\n", tree->rightchild->key);
    (element < (tree->key))? insertleft(tree, element): insertright(tree, element);
}

int insertleft(struct Node *self, int element)
{
    printf("left insertion\n");
    if (self->leftchild != &emptynode)
    {
        insert(self->leftchild, element);
    }
    else 
    {
        struct Node left = {.key = element, .height = 1, .parent = self, .leftchild = &emptynode, .rightchild = &emptynode};
        self->leftchild = &left;
        self->height = 2;
        struct Node *node = self;
        while(node->parent != &emptynode)
        {
            node = node->parent;
            int rotationflag = self->leftchild->height - self->rightchild->height;
            if (abs(rotationflag) > 1)
            {
                rotate(node, rotationflag);
                return 0;
            } 
            else
            {
                node->height = 1+max(node->leftchild->height, node->rightchild->height);
            }
        }
    }
    return 0;
}

int insertright(struct Node *self, int element)
{
    printf("right insertion\n");
    printf("rightchild node: %d\n", self->rightchild->key);

    if (self->rightchild != &emptynode)
    {
        //printf("self node: %d\n", self->rightchild->key);
        insert(self->rightchild, element);
    } 
    else
    {
        struct Node right = {.key = element, .height = 1, .parent = self, .leftchild = &emptynode, .rightchild = &emptynode};
        self->rightchild = &right;
        self->height = 2;
        struct Node *node = self;
        while(node->parent != &emptynode)
        {
            node = node->parent;
            int rotationflag = node->leftchild->height - node->rightchild->height;
            if (abs(rotationflag) > 1)
            {
                rotate(node, rotationflag);
                return 0;
            } 
            else
            {
                node->height = 1+max(node->leftchild->height, node->rightchild->height);
            }
        }
    }

    return 0;
}

void rotate(struct Node *self, int flag)
{
    if (flag > 0)
    {
        if (self->leftchild->leftchild->height == self->height -1)
            leftRotation(self);
        else
        {
            rightRotation(self->leftchild);
            leftRotation(self);
        }
    } 
    else
    {
        if (self->rightchild->rightchild->height == self->height -1)
            rightRotation(self);
        else
        {
            leftRotation(self->rightchild);
            rightRotation(self);
        }
    }
}

void leftRotation(struct Node *self)
{
    printf("left rotation\n");
    struct Node *u = self->parent;
    struct Node *a = self;
    struct Node *b = self->leftchild;
    struct Node *B = b->rightchild;
    a->parent = b;
    b->rightchild = a;
    a->leftchild = B;
    B->parent = a;
    b->parent = u;

    if (u->rightchild == a)
        u->rightchild = b;
    else
        u->leftchild = b;

    b->height = a->height;
    a->height--;
}

void rightRotation(struct Node *self)
{
    printf("right rotation\n");
    struct Node *u = self->parent;
    struct Node *a = self;
    struct Node *b = self->rightchild;
    struct Node *B = b->leftchild;
    a->parent = b;
    b->leftchild = a;
    a->rightchild = B;
    B->parent = a;
    b->parent = u;

    if (u->rightchild == a)
        u->rightchild = b;
    else
        u->leftchild = b;

    b->height = a->height;
    a->height--;
}

int query(struct Node *self, int value)
{
    static int result;
    if (self == &emptynode)
        return result;
    if (self->key == value)
        return value;
    else if (self->key > value)
        return query(self->leftchild, value);
    else
    {
        result = self->key;
        return query(self->rightchild, value);
    }
}

0 个答案:

没有答案