链接列表,元素丢失

时间:2017-10-19 20:02:42

标签: c linked-list

我试图将一个节点插入到链接列表的末尾,并且一切都像奇迹一样,但是,当涉及最后一个元素时,它会打印null。问题必须在else块中,我在想,当我查找最后一项时,它可能指向NULL而不是nextNULL的元素

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


#define HOW_MANY 7
char *names[HOW_MANY]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim",
              "Harriet"};
int ages[HOW_MANY]= {22, 24, 106, 6, 18, 32, 24};

struct person {
  int age;
  char *name;
    struct person *next;
};


struct person* insert_end(struct person *ptr, char *name, int age)
{
  //The new location for the new person
  struct person* newPer = malloc(sizeof(struct person));
    if (newPer == NULL) {
        printf("something went wrong allocating the memory\n");
        exit(1);
    }

  newPer -> name = name;
  newPer -> age = age;
  //Make its next points previous element
  if (ptr->next == NULL) {
    newPer -> next = ptr;


    return newPer;
  }
  else {
    struct person *tmp = ptr;
    while(tmp -> next != NULL){
      tmp = tmp -> next;

    }
    printf("%s", tmp -> name);
    tmp -> next = newPer;


    //if(strcmp("Harriet",name)==0)
    return ptr;
  }
  //return the new address so that it becomes the new HEAD of the linked list
    return newPer;
}


int main(int argc, char **argv)
{
    //This is the head of the list
    struct person *HEAD = NULL;
    HEAD = malloc(sizeof(struct person));
    if (HEAD == NULL) {
        printf("something went wrong allocating the memory");
        exit(1);
    }


    int i;
  //insert a new person and make HEAD points to it, so that HEADS
  //will be pointing to the last element added to the linked list.
  for (i = 0; i < HOW_MANY; i++){
        HEAD = insert_end (HEAD, names[i], ages[i]);
    }

  struct person* tmp = HEAD;
  //We can use the member name(pointer) as the condition, if we did then extra
  //unwanted elements added to the linked list by accident won't be printed
  while (tmp != NULL){
    if (tmp -> next != NULL)
      printf("The name is %s, the age is %d years\n", tmp->name, tmp->age);

    //store the pointer in a tmp so than we can access the next pointer then
    //free tmp
    struct person* prevtmp = tmp;
    tmp = tmp -> next;
    free(prevtmp);
  }
}

输出

The name is Simon, the age is 22 years
The name is (null), the age is 0 years
The name is Suzie, the age is 24 years
The name is Alfred, the age is 106 years
The name is Chip, the age is 6 years
The name is John, the age is 18 years
The name is Tim, the age is 32 years

4 个答案:

答案 0 :(得分:1)

只需将if (tmp -> next != NULL)更改为if (tmp != NULL)即可。您忘记了列表中的最后一个节点没有“下一个”节点。

答案 1 :(得分:1)

确保newPer->next设置为NULL

  newPer -> name = name;
  newPer -> age = age;
  newPer -> next = NULL;

您的哨兵HEAD也是如此。

    HEAD = malloc(sizeof(struct person));
    if (HEAD == NULL) {
         printf("something went wrong allocating the memory");
        exit(1);
    }
    HEAD->name = "HEAD";
    HEAD->age = -1;
    HEAD->next = NULL;

答案 2 :(得分:0)

您将*HEAD初始化为NULL,但您从未在某个人身上填充该地址,以便NULL被推到最后并留在那里。尝试在函数顶部添加:

if (*ptr == NULL){
    newPer = ptr
}
else {
    struct person* newPer = malloc(sizeof(struct person));
    if (newPer == NULL) {
        printf("something went wrong allocating the memory\n");
        exit(1);
    }
}

您可能需要更改其他几个条件,但您的想法是需要检查newPer是否是列表中的第一个条目,并更改处理该情况的方式。

答案 3 :(得分:0)

首先,未初始化的列表头应始终为NULL。插入函数应该检测到这一点并简单地返回正确初始化的第一个节点。之后,您可以根据p->next是否NULL建立逻辑。您几乎必须重写一些代码以使其正确。对于'insert_end'应始终返回它所传递的头指针,'insert_front'应始终返回新节点,因为它总是新的头。