Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
156 views
in Technique[技术] by (71.8m points)

c - Implementing an AVL tree, but getting seg fault on large data file insertion

Creating a dictionary comparison program utilizing avl_tree, but getting a segfault when reading in a large file 200,000+ unique words. Smaller files seem to work fine.

A couple of my thoughts might be my word_compre function which may interfere with the rotation. Or likely I have implemented the rotation incorrectly.

// String compare based on alphabetical order
int word_compare(char *word, struct tree_node *root)
{
    return strcasecmp(word, root->word);
}

// Get the maximum of two integers
int get_max(int int_a, int int_b)
{
    if (int_a > int_b)
        return int_a;
    else
        return int_b;
}

// Get the height of the tree
int get_height(struct tree_node *root)
{
    if (root == NULL)
        return 0;
    else
        return root->height;
}

// Determine if the tree or subtree is unbalanced by comparing the max height
// of the left and right branches
int get_balance(struct tree_node *root)
{
    if (root == NULL)
        return 0;
    else
        return get_height(root->left) - get_height(root->right);
}

// Rotate left subtree rooted with right child node
struct tree_node *left_rotate(struct tree_node* root)
{
    // Store the right child node to rotate
    struct tree_node *right_child = root->right;

    // Store the left of the right child node to rotate
    struct tree_node *subtree = right_child->left;

    // Perform rotation
    right_child->left = root;
    root->right = subtree;

    // Update heights
    root->height = get_max(get_height(root->left),
                   get_height(root->right)) + 1;
    right_child->height = get_max(get_height(right_child->left),
                      get_height(right_child->right)) + 1;

    return right_child;
}

// Rotate right subtree rooted with left child node
struct tree_node *right_rotate(struct tree_node *root)
{
    // Store the left child node to rotate
    struct tree_node *left_child = root->left;

    // Store the right of the left child node to rotate
    struct tree_node *subtree = left_child->right;

    // Perform rotation
    left_child->right = root;
    root->left = subtree;

    // Update heights
    root->height = get_max(get_height(root->left),
                   get_height(root->right)) + 1;
    left_child->height = get_max(get_height(left_child->left),
                     get_height(left_child->right)) + 1;

    return left_child;
}

// Insert new node into a tree
struct tree_node *insert_node(struct tree_node *root, char *word, int fp_num)
{
    // Viable spot found, insert a new node
    if (root == NULL) {

        #ifdef DEBUG
        printf("INSERTED NODE
");
        printf("WORD: %s
", word);
        #endif

        if (fp_num == 1) {
            // Allocate a new node
            root = (struct tree_node *)malloc(sizeof(struct tree_node));

            // Fail to allocate a new node
            if (root == NULL) {
                printf("
Failed to allocate a node
");
                return NULL;
            }
            // Initialize the new node
            else {
                root->word = strdup(word);
                root->count = 1;
                root->left = NULL;
                root->right = NULL;
                root->height = 1;
                return root;
            }
        }
        else {
            return root;
        }
    }

    int exist = word_compare(word, root);

    if (exist < 0) {
        root->left = insert_node(root->left, word, fp_num);
    }
    else if (exist > 0) {
        root->right = insert_node(root->right, word, fp_num);
    }
    else {
        if (fp_num != 1 && root->count == fp_num - 1) {
            root->count = fp_num;
        }
    }


    // Check the balance of the tree
    int balance = get_balance(root);

    // If the tree is imbalanced, fixed them with one of the following cases
    // Left-Left-Case
    if (balance > 1 && (word_compare(word, root->left) < 0))
        return right_rotate(root);

    // Right-Right-Case
    if (balance < -1 && (word_compare(word, root->right) > 0))
        return left_rotate(root);

    // Left-Right-Case
    if (balance > 1 && (word_compare(word, root->left) > 0)) {
        root->left = left_rotate(root->left);
        return right_rotate(root);
    }
    // Right-Left-Case
    if (balance < -1 && (word_compare(word, root->right) < 0)) {
        root->right = right_rotate(root->right);
        return left_rotate(root);
    }

    return root;
}

// Perform in-order traversal sort of the tree and display results
void in_order(struct tree_node *root, int fp_num)
{
    if (root == NULL)
        return;

    // Recur until the left most node
    if (root->left)
        in_order(root->left, fp_num);

    // Find the amount of dollars from the cents and puts the
    // remainder after a decimal point
    if (fp_num != 1 && root->count == fp_num)
        printf("%s
", root->word);

    // Recur until the right most node
    if (root->right)
        in_order(root->right, fp_num);
}


// Delete tree
void free_tree(struct tree_node *root)
{
    if (root != NULL)
    {
        free_tree(root->left);
        free(root->word);
        free_tree(root->right);
        free(root);
    }
}
question from:https://stackoverflow.com/questions/65849204/implementing-an-avl-tree-but-getting-seg-fault-on-large-data-file-insertion

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Fixed it. Did not update current node/root height in the insertion function.

// Insert new node into a tree
struct tree_node *insert_node(struct tree_node *root, char *word, int fp_num)
{
    // Viable spot found, insert a new node
    if (root == NULL) {

        #ifdef DEBUG
        printf("INSERTED NODE
");
        printf("WORD: %s
", word);
        #endif

        if (fp_num == 1) {
            // Allocate a new node
            root = (struct tree_node *)malloc(sizeof(struct tree_node));

            // Fail to allocate a new node
            if (root == NULL) {
                printf("
Failed to allocate a node
");
                return NULL;
            }
            // Initialize the new node
            else {
                root->word = strdup(word);
                root->count = 1;
                root->left = NULL;
                root->right = NULL;
                root->height = 1;
                return root;
            }
        }
        else {
            return root;
        }
    }

    int word_exist = word_compare(word, root);

    if (word_exist < 0) {
        root->left = insert_node(root->left, word, fp_num);
    }
    else if (word_exist > 0) {
        root->right = insert_node(root->right, word, fp_num);
    }
    else {
        if (fp_num != 1 && root->count == fp_num - 1) {
            root->count = fp_num;
        }
    }

    // Update height of current node
    root->height = 1 + get_max(get_height(root->left), get_height(root->right));

    // Check the balance of the tree
    int balance = get_balance(root);

    // If the tree is imbalanced, fixed them with one of the following cases
    // Left-Left-Case
    if (balance > 1 && (word_compare(word, root->left) < 0))
        return right_rotate(root);

    // Right-Right-Case
    if (balance < -1 && (word_compare(word, root->right) > 0))
        return left_rotate(root);

    // Left-Right-Case
    if (balance > 1 && (word_compare(word, root->left) > 0)) {
        root->left = left_rotate(root->left);
        return right_rotate(root);
    }
    // Right-Left-Case
    if (balance < -1 && (word_compare(word, root->right) < 0)) {
        root->right = right_rotate(root->right);
        return left_rotate(root);
    }

    return root;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...