0

所以这个函数(tmap_insert)正在做一些奇怪的事情。我在一个循环中调用它,并且由于某种原因,每当我添加一个新项目时,它都会覆盖树中所有先前添加的项目的项目->名称(但不是项目-> val!),并将其命名为最近的添加。我已经在这里发布了我的代码供您查看——它很长,但我对此无能为力。

此外,我还包含了相关的结构,以及在循环中调用它的函数。

int tmap_insert(TMAP_PTR t, char * name, double val){
    TMAP_PTR parent = malloc(sizeof(struct tmap_struct));
    TMAP_PTR new = malloc(sizeof(struct tmap_struct));
    NAME_VAL* temp = malloc(sizeof(NAME_VAL));
    temp->name = name;
    temp->value = val;        
    new->item = temp;    
    new->size = 1;
    new->height = 0;
    while (t != NULL)
    {
        t->size = t->size + 1;
        if (val > (t->item)->value)
        {
            parent = t;
            t = t->right;
        }
        else if (val < (t->item)->value)
        {
            parent = t;
            t = t->left;
        }
    }
    if (parent != NULL)
    {
        new->parent = parent;
        if (val > (parent->item)->value)
        {
            parent->right = new;
        }
        else if (val < (parent->item)->value)
        {
            parent->left = new;
        }
    }
    TMAP_PTR unbalanced = malloc(sizeof(struct tmap_struct));
    unbalanced = NULL;
    TMAP_PTR iterator = malloc(sizeof(struct tmap_struct));
    iterator = new->parent;
    while (iterator != NULL)
    {
        if (iterator->left != NULL && iterator->right != NULL)
        {
            if ((iterator->left)->size > (2*((iterator->right)->size) + 1) || (iterator->right)->size > (2*((iterator->left)->size) + 1))
            {
                unbalanced = iterator;
            }
            if ((iterator->left)->height > (iterator->right)->height)
            {
                iterator->height = (iterator->left)->height + 1;
            }
            else
            {
                iterator->height = (iterator->right)->height + 1;
            }
        }
        else if (iterator->left != NULL)
        {
            if ((iterator->left)->size > 1)
            {
                unbalanced = iterator;
            }
            iterator->height = (iterator->left)->height + 1;
        }
        else
        {
            if ((iterator->right)->size > 1)
            {
                unbalanced = iterator;
            }
            iterator->height = (iterator->right)->height + 1;
        }        
        iterator = iterator->parent;
    }
    if (unbalanced != NULL)
    {
        NAME_VAL **arr = malloc(unbalanced->size * sizeof(NAME_VAL*));
        int i;        
        for (i = 0; i < unbalanced->size; i++)
        {
            arr[i] = malloc(sizeof(NAME_VAL));
        }
        int *index = malloc(sizeof(int));
        *index = 0;        
        arr = make_arr(unbalanced, arr, index);

        int pos = ((unbalanced->size) / 2);

        TMAP_PTR head = malloc(sizeof(struct tmap_struct));
        head->size = 1;
        head->height = 0;
        head->item = arr[pos];
        rebalance(arr, 0, pos-1, head);
        rebalance(arr, pos+1, unbalanced->size, head);
        unbalanced->parent = head->parent;
        if ((unbalanced->parent)->right == unbalanced)
        {
            (unbalanced->parent)->right = head;
        }
        else
        {
            (unbalanced->parent)->left = head;
        }
    }
    return 1;
}


TMAP_PTR tmap_create(char *fname){
    printf("%s", fname);
    fflush(stdout);
    FILE *src;
    src = fopen(fname, "r");
    if (src == NULL)
    {
        printf("File could not open!\n");
        return;
    }
    double value;
    char name[20];

    TMAP_PTR head = malloc(sizeof(struct tmap_struct));
    head->size = 1;
    head->height = 0;

    fscanf(src, "%s", name);
    fscanf(src, "%lf", &value);
    head->item = malloc(sizeof(NAME_VAL));
    (head->item)->value = value;
    (head->item)->name = name;

    while (fscanf(src, "%s %lf", name, &value) == 2)
    {
        printf("%s", name);
        fflush(stdout);
        tmap_insert(head, name, value);
    }
    return head;

}

struct tmap_struct{
    TMAP_PTR parent;
    TMAP_PTR left;
    TMAP_PTR right;
    int height;
    int size;
    NAME_VAL* item;
};

typedef struct name_val {
    char *name;
    double value;
}NAME_VAL;
4

1 回答 1

0

In tmap_create(char *fname) you allocate an array of char for name, then in each step of your loop you read in it the new value of name, and pass it to the function tmap_insert, where you create a new node and store in it the pointer to the char array. So, obviously, all the nodes of the tree point to the same char array, and when you store in it a new string, all the nodes see the new value. The solution is to allocate a new char array for each name you have to store. You should replace the while loop in tmap_create() with:

char* name = malloc(20*sizeof(char));
while (fscanf(src, "%s %lf", name, &value) == 2)
    {
        printf("%s", name);
        fflush(stdout);
        tmap_insert(head, name, value);
        name = malloc(20*sizeof(char));
    }    
于 2013-04-29T09:26:20.467 回答