C语言动态分配内存建立链表


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

typedef struct student {
  int id;
  char name[200];
  char gender;
  int age;
  struct student *next;
} Student;

int main(void) {
  Student *head = NULL, *tail = NULL;

  // 从键盘输入4个学生的数据
  for (int i = 0; i < 4; i++) {
    // 动态分配内存
    Student *node = (Student*)malloc(sizeof(Student));
    if (node == NULL) {
      printf("Memory allocation failed.\n");
      exit(1);
    }

    // 从键盘输入学生数据
    printf("Enter student %d data:\n", i+1);
    scanf("%d%s %c%d", &node->id, node->name, &node->gender, &node->age);

    // 将新节点插入链表
    if (head == NULL) {
      // 如果链表为空,则新节点为链表的第一个节点
      head = node;
      tail = node;
    } else {
      // 将新节点插入到链表的最后一个节点之后
      tail->next = node;
      tail = node;
    }
  }

  // 从键盘输入一个年龄
  int age;
  printf("Enter an age: ");
  scanf("%d", &age);

  // 删除链表中所有包含此年龄的节点
  Student *curr = head, *prev = NULL;
  while (curr != NULL) {
    if (curr->age == age) {
      // 如果找到了包含此年龄的节点,则从链表中删除它
      if (prev == NULL) {
        // 如果当前节点是链表的第一个节点,则将头指针指向下一个节点
        head = curr->next;
      } else {
        // 将前一个节点的 next 指针指向当前节点的下一个节点
        prev->next = curr->next;
}

  // 释放当前节点的内存
  free(curr);

  // 将当前节点更新为前一个节点
  curr = prev;
}

// 更新 prev 和 curr 指针
prev = curr;
curr = curr->next;
}

// 输出剩余节点的数据
for (curr = head; curr != NULL; curr = curr->next) {
printf("%d %s %c %d\n", curr->id, curr->name, curr->gender, curr->age);
}
return 0;
}
这个代码还不能执行成功。我想知道是看看哪里有问题。

参考代码实现如下,望采纳

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

#define MAX_NAME_LEN 20

typedef struct student {
  int id;
  char name[MAX_NAME_LEN+1];
  char gender;
  int age;
  struct student *next;
} Student;

Student *create_student(int id, const char *name, char gender, int age) {
  Student *s = (Student *)malloc(sizeof(Student));
  if (s == NULL) {
    printf("Error: failed to allocate memory for student.\n");
    exit(1);
  }

  s->id = id;
  strncpy(s->name, name, MAX_NAME_LEN);
  s->name[MAX_NAME_LEN] = '\0';
  s->gender = gender;
  s->age = age;
  s->next = NULL;

  return s;
}

void insert_student(Student **head, Student *s) {
  if (*head == NULL) {
    *head = s;
  } else {
    Student *p = *head;
    while (p->next != NULL) {
      p = p->next;
    }
    p->next = s;
  }
}

void delete_student(Student **head, int age) {
  Student *p = *head;
  Student *prev = NULL;
  while (p != NULL) {
    if (p->age == age) {
      if (prev == NULL) {
        *head = p->next;
      } else {
        prev->next = p->next;
      }
      free(p);
      p = prev;
    }
    prev = p;
    p = p->next;
  }
}

void print_students(const Student *head) {
  const Student *p = head;
  while (p != NULL) {
    printf("%d %s %c %d\n", p->id, p->name, p->gender, p->age);
    p = p->next;
  }
}

int main() {
  Student *head = NULL;

  int id;
  char name[MAX_NAME_LEN+1];
  char gender;
  int age;

  for (int i = 0; i < 4; i++) {
    scanf("%d", &id);
    scanf("%s", name);
    scanf(" %c", &gender);
    scanf("%d", &age);

    Student *s = create_student(id, name, gender, age);
    insert_student(&head, s);
  }

  scanf("%d", &age);
  delete_student(&head, age);

  print_students(head);

  return 0;
}

修改完善如下,供参考:

#include <stdio.h>
#include <stdlib.h>
typedef struct student {
  int  id;
  char name[200];
  char gender;
  int  age;
  struct student *next;
} Student;

int main(void)
{
  Student *head = NULL, *tail = NULL;

  // 从键盘输入4个学生的数据
  for (int i = 0; i < 4; i++) {
    // 动态分配内存
    Student *node = (Student*)malloc(sizeof(Student));
    if (node == NULL) {
      printf("Memory allocation failed.\n");
      exit(1);
    }

    // 从键盘输入学生数据
    printf("Enter student %d data:\n", i+1);
    scanf("%d %s %c %d", &node->id, node->name, &node->gender, &node->age);
    //scanf("%d%s %c%d", &node->id, node->name, &node->gender, &node->age);
    // 将新节点插入链表
    if (head == NULL) {
      // 如果链表为空,则新节点为链表的第一个节点
      head = node;
      tail = node;
    } else {
      // 将新节点插入到链表的最后一个节点之后
      tail->next = node;
      tail = node;
    }
  }

  // 从键盘输入一个年龄
  int age;
  printf("Enter an age: ");
  scanf("%d", &age);

  // 删除链表中所有包含此年龄的节点
  Student *curr = head, *prev = NULL;
  while (curr != NULL) {
    if (curr->age == age)
    {
        // 如果找到了包含此年龄的节点,则从链表中删除它
        if (prev == NULL) {
            // 如果当前节点是链表的第一个节点,则将头指针指向下一个节点
            head = curr->next;
            free(curr);
            curr = head;
        } else {
            // 将前一个节点的 next 指针指向当前节点的下一个节点
            prev->next = curr->next;
            //}
            // 释放当前节点的内存
            free(curr);
            // 将当前节点更新为前一个节点
            curr = prev;
        }
    }
    else{ // 更新 prev 和 curr 指针
      prev = curr;
      curr = curr->next;
    }
  }
  // 输出剩余节点的数据
  for (curr = head; curr != NULL; curr = curr->next) {
       printf("%d %s %c %d\n", curr->id, curr->name, curr->gender, curr->age);
  }
  return 0;
}