尝试创建字符串的avl树时出现分段错误

时间:2014-08-07 14:01:08

标签: c data-structures binary-tree avl-tree

我来自Java背景,我认为学习c很好,因为我决定阅读一本数据结构书,并在阅读时学习语言语法,但现在我遇到了问题,我试图创建一个avl树,它的键值将是一个字符串,但是当我尝试将我的书中使用int的示例转换为char *时,编译器只显示了分段故障错误:( 这是我的代码:

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

// An AVL tree node
struct node {
    char *key;
    struct node *left;
    struct node *right;
    int height;
};

// A utility function to get maximum of two integers
int max(int a, int b);

// A utility function to get height of the tree
int height(struct node *N) {
    if (N == NULL)
        return 0;
    return N->height;
}

// A utility function to get maximum of two integers
int max(int a, int b) {
    return (a > b) ? a : b;
}

/* Helper function that allocates a new node with the given key and
 NULL left and right pointers. */
struct node* newNode(char *key) {
    struct node* node = (struct node*) malloc(sizeof(struct node));
    node->key = strdup(key);
    node->left = NULL;
    node->right = NULL;
    node->height = 1;  // new node is initially added at leaf
    return (node);
}

// A utility function to right rotate subtree rooted with y
// See the diagram given above.
struct node *rightRotate(struct node *y) {
    struct node *x = y->left;
    struct node *T2 = x->right;

    // Perform rotation
    x->right = y;
    y->left = T2;

    // Update heights
    y->height = max(height(y->left), height(y->right)) + 1;
    x->height = max(height(x->left), height(x->right)) + 1;

    // Return new root
    return x;
}

// A utility function to left rotate subtree rooted with x
// See the diagram given above.
struct node *leftRotate(struct node *x) {
    struct node *y = x->right;
    struct node *T2 = y->left;

    // Perform rotation
    y->left = x;
    x->right = T2;

    //  Update heights
    x->height = max(height(x->left), height(x->right)) + 1;
    y->height = max(height(y->left), height(y->right)) + 1;

    // Return new root
    return y;
}

// Get Balance factor of node N
int getBalance(struct node *N) {
    if (N == NULL)
        return 0;
    return height(N->left) - height(N->right);
}

struct node* insert(struct node* node, char *key) {
    /* 1.  Perform the normal BST rotation */
    if (node == NULL)
        return (newNode(key));

    if (strcmp(key, node->key) < 0)
        node->left = insert(node->left, key);
    else
        node->right = insert(node->right, key);

    /* 2. Update height of this ancestor node */
    node->height = max(height(node->left), height(node->right)) + 1;

    /* 3. Get the balance factor of this ancestor node to check whether
     this node became unbalanced */
    int balance = getBalance(node);

    // If this node becomes unbalanced, then there are 4 cases

    // Left Left Case
    if (balance > 1 && key < node->left->key)
        return rightRotate(node);

    // Right Right Case
    if (balance < -1 && key > node->right->key)
        return leftRotate(node);

    // Left Right Case
    if (balance > 1 && key > node->left->key) {
        node->left = leftRotate(node->left);
        return rightRotate(node);
    }

    // Right Left Case
    if (balance < -1 && key < node->right->key) {
        node->right = rightRotate(node->right);
        return leftRotate(node);
    }

    /* return the (unchanged) node pointer */
    return node;
}

// A utility function to print preorder traversal of the tree.
// The function also prints height of every node
void preOrder(struct node *root) {
    if (root != NULL) {
        printf("%d ", root->key);
        preOrder(root->left);
        preOrder(root->right);
    }
}

/* Drier program to test above function*/
int main() {
    struct node *root = NULL;

    /* Constructing tree given in the above figure */
    root = insert(root, "10");
    root = insert(root, "20");
    root = insert(root, "30");
    root = insert(root, "40");
    root = insert(root, "50");
    root = insert(root, "25");

    /* The constructed AVL Tree would be
     30
     /  \
         20   40
     /  \     \
       10  25    50
     */

    printf("Pre order traversal of the constructed AVL tree is \n");
    preOrder(root);

    return 0;
}

3 个答案:

答案 0 :(得分:1)

当您将密钥类型从int更改为char *时,您已正确更改了插入步骤以使用strcmp,但重新平衡步骤仍然使用<运算符字符串。这打破了代码对某些节点为非NULL的假设。通过更新左/左/右/等情况的条件也使用strcmp,代码按预期工作。

另外,正如我在评论中提到的,您应该将printf更改为使用%s而不是%d

答案 1 :(得分:1)

您需要使用 strcmp ,因为您要从 int 转换为 char ,你可以学习更多关于这个主题的知识,阅读关于伟大的c编程语言的标准书籍

答案 2 :(得分:0)

rightRotate() x->right NULL newNode()中,您需要在分配到T2之前调用{{1}}来创建节点。我怀疑在整个代码中还有其他类似的地方。