我在链接列表中插入项目时遇到问题。所有元素最终都具有插入到最后一个中的相同*数据内容。该程序成功编译。我使用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;
}
答案 0 :(得分: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()
中最初为NULL。
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);
}
}
答案 1 :(得分:1)
typedef struct Node{
void* data; // Make it as int or any other data type
struct Node* next;
} *node;
在函数inputSequence()中,您在最开始为num分配内存,并在每次添加节点时使node->数据指向此内存。因此,链表的每个节点的数据指针指向相同的内存位置,因此包含相同的值。
如果您仍想继续将数据作为void指针,请为while循环的每次迭代分配num,并将其传递给insert函数。
while((scanf("%d", num) != EOF)){
num = malloc(sizeof(int);
insert(input, (void *)num);
count++;
}