为什么我的链表只包含一个节点,即使我添加了多个节点?

时间:2014-06-12 04:52:10

标签: c linked-list

我正在尝试制作一个简单的链表编程。 这是我的代码 我预计输出有4行

Tugi 1

第2号法案

Sweet 3

Miharu 4

但输出仅为Tugi 1。 我的代码出了什么问题?

我被要求做另一个关于链表的任务,但我的教授没有解释清楚,所以我只是想做一个简单的编程来测试链表。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _member{
    char name[20];
    int number;
    struct _member* next; //pointer to the next structure
}
MEMBER;

void AddMember(MEMBER* start, char* namae, int num);

MEMBER* NewMember(char* namae, int num);
    //void FreeLink(MEMBER* start);
void PrintMember(MEMBER* start);

int main(){
    static int serialNum=1;
    MEMBER* start = NewMember("Tugi", serialNum++);
    AddMember(start, "Bill", serialNum++);
    AddMember(start, "Sweet", serialNum++);
    AddMember(start, "Miharu", serialNum++);
    PrintMember(start);
    free(start);
    return 0;
}

MEMBER* NewMember(char* namae, int num){
    MEMBER* this;
    this = (MEMBER*)malloc(sizeof(MEMBER)); //allocate the memory
    strcpy(this->name, namae); //copy the name
    this->number = num;
    this->next = NULL; //The next is NULL
    return(this);
}
void AddMember(MEMBER* start, char* namae, int num){
    MEMBER* p=start;
    while(p!=NULL) p = p->next;
    p = (MEMBER*)malloc(sizeof(MEMBER));
    strcpy(p->name, namae);
    p->number = num;
    p->next = NULL;
}
void PrintMember(MEMBER* start)
{
    MEMBER* p;
    for(p=start; p!=NULL; p=p->next){
        printf("%s %d\n", p->name, p->number);
    }
}

3 个答案:

答案 0 :(得分:2)

在AddMember函数中,您不会修改列表中的最后一个元素以指向新元素,因此永远不会创建链接列表

在添加新

之前修改最后一个元素

还要确保为malloc包含stdlib.h,因为不应该强制转换malloc()

void AddMember(MEMBER* start, char* namae, int num)
{
  MEMBER* p=start;
  MEMBER* q=NULL;
  while(p!=NULL) 
  {
    q = p; 
    p = p->next;
  }
  p = malloc(sizeof(MEMBER));
  strcpy(p->name, namae);
  p->number = num;
  p->next = NULL;
  if ( q != NULL )
  {
    q->next = p;
  }
}

答案 1 :(得分:1)

您的add函数永远不会将链中的最后一个指针设置为正在分配的新节点。它只获取其值(为NULL),然后创建一个新节点,将其地址存储在本地指针p中。然后,新分配的节点将填充数据,但仍与原始列表分离。

有多种方法可以正确地执行此操作。我更喜欢以下内容,因为它允许您使用AddMember来添加所有,而不必像当前那样使用特殊情况进行第一次添加。它利用指向指针的方法:

void AddMember(MEMBER** start, char const* name, int num)
{
    // loop until the pointer who's address is stored in
    //  the start parameter is NULL.
    while (*start)
        start = &(*start)->next;

    // start now contains the address of the last pointer
    //  in our linked list. allocate a new node, saving the
    //  address in that pointer.
    *start = NewMember(name, num);
}

您还需要一种释放整个列表的机制;不只是第一个节点。 free()不会削减它。再次,使用指针指针:

void FreeMembers(MEMBER** start)
{
    while (*start)
    {
        MEMBER *tmp = *start;
        *start = tmp->next;
        free(tmp);
    }
}

main()中这样调用:

int main()
{
    static int serialNum=1;
    MEMBER* start = NULL; // Note: MUST be NULL on inception.

    AddMember(&start, "Tugi", serialNum++);
    AddMember(&start, "Bill", serialNum++);
    AddMember(&start, "Sweet", serialNum++);
    AddMember(&start, "Miharu", serialNum++);

    PrintMember(start);

    FreeMembers(&start);

    return 0;
}

祝你好运。

答案 2 :(得分:0)

因为你覆盖了最后一个链接,而不是设置它的下一个链。

因此,在第一次添加时,您将获得Tugi,然后将其替换为后续版本。您需要将p->next设置为新创建的链接。

找到最后一个链接(p)后,创建一个新链接(new_p),然后最后执行:p->next = new_p;(实际上是将新链接添加到结束)。