1

我在链接列表中插入项目时遇到问题。所有元素最终都具有最后插入的相同 *data 内容。程序编译成功。我使用 gcc 和 gdb。我是编码新手,所以如果您在我的编程风格中看到任何麻烦,请提及。

typedef struct Node{
    void* data;
    struct Node* next;
} *node;

node allocate(){
    node current = malloc(sizeof(struct Node));
    current->data = NULL;
    current->next = NULL;
    return current;
}


void insert(node *head, void *data){
    // if head has no data then set the data on head and return
    if(((*head)->data == NULL)&&((*head)->next == NULL)){
        (*head)->data = data;
        return;
    }

    node newHead = allocate();
    newHead->data = data;
    newHead->next = *head;
    *head = newHead;
    //printf("Node Data : %d\tNext Node Data : %d",
        //*(int *)((*head)->data), *(int *)((*head)->data));
}

int main(int argc, char *argv[]){
    node head = allocate();
    int count = inputSequence(&head);
    int *aod = calloc((size_t) count, sizeof(int));
    generateAOD(head, aod);
    if(checkJolly(aod, count) == TRUE)
        printf("Jolly\n");
    else
        printf("Not Jolly\n");

    return 0;
}

int inputSequence(node *input){
    int *num = malloc(sizeof(int));
    int count = 0;

    while((scanf("%d", num) != EOF)){
        insert(input, (void *)num);
        count++;
    }
    traverse(*input, fn);
    return count;
}
4

2 回答 2

2

您的插入逻辑不存在。通过尝试以您正在使用的方式管理链接列表,您实际上使您的生活变得更加艰难。

头指针本身应该指示列表是否为空。如果为NULL,则为空。如果不是,则有数据。相应地对插入逻辑进行编码。

而你inputSequence的完全崩溃了。它只分配一个数据点,然后为每次插入使用相同的数据分配。每次插入都需要一个。

首先,更改allocate()以接受正在插入的数据。它将使剩余的代码不那么混乱:

node allocate(void *data)
{
    node current = malloc(sizeof(*current));
    current->data = data;
    current->next = NULL;
    return current;
}

其次,根据需要通过分配新节点来插入。

void insert(node *head, void *data)
{
    node p = allocate(data);
    p->next = *head;
    *head = p;
}

接下来,修复inputSequence()为每个条目正确分配内存:

int inputSequence(node *input)
{
    int count = 0;
    int num = 0;

    // note: check for number of params *successfully* parsed.
    //  if it isn't 1, its time to leave the loop.
    while(scanf("%d", &num) == 1)
    {
        int *data = malloc(sizeof(num));
        *data = num;
        insert(input, data);
        ++count;
    }
    return count;
}

最后,确保您的头指针在main().

int main(int argc, char *argv[])
{
    node head = NULL;

    // load linked list
    inputSequence(&head);

    // ... the rest of your code....;

    return 0;
}

综上所述,“我的列表是否为空”的逻辑答案很简单if (!head),这使得遍历之类的事情变得微不足道。

void traverse(node ptr, void (*pfn)(void *))
{
    while (ptr)
    {
        pfn(ptr->data);
        ptr = ptr->next;
    }
}

释放列表同样简单:

void destroy(node *head)
{
    while (*head)
    {
        node p = *head;
        *head = p->next;
        free(p->data);
        free(p);
    }
}
于 2013-09-19T08:55:05.547 回答
1
   typedef struct Node{
         void* data; // Make it as int or any other data type
         struct Node* next;
   } *node;

在函数 inputSequence() 中,您在一开始就为 num 分配内存,并在每次添加节点时使 node->data 指向该内存。因此,链表的每个节点的数据指针都指向相同的内存位置,因此包含相同的值。

如果您仍想继续使用数据作为 void 指针,请为 while 循环的每次迭代分配 num 并将其传递给 insert 函数。

    while((scanf("%d", num) != EOF)){
        num = malloc(sizeof(int);
        insert(input, (void *)num);
        count++;
    }
于 2013-09-19T08:52:26.907 回答