链表的输入数据(追加法)、查找结点、插入结点、删除结点、计算结点数据
要求:给定链表的头结点指针(head),要求分别定义函数append_node, search_list, insert_node,delete_node, calc_average方法,实现链表数据的输入、查找、插入、删除和计算数据平均值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student
{
char name[20];
int num;
float grades[5];
float ave;
struct Student *next;
};
typedef struct Student STU;
void append_node(STU *head); // 追加法插入链表结点
void print_list(STU *head); //遍历链表
void insert_node(STU *head, STU* p); // 向链表中插入一个结点
void delete_note(STU *head, int num); // 删除链表中指定学号的结点
char* search_list(STU *head, int num); // 查找链表中某个元素是否存在
void calc_average(STU *head); // 计算每个结点的平均成绩
int main()
{
STU *head, *p;
int num;
// 初始化head结点
head = (STU*) malloc (sizeof(STU));
head->next = NULL;
// 调用append方法输入链表数据
append_node(head);
print_list(head);
/*
// 查找 10003
char *s = search_list(head, 10003);
if (s != NULL)
printf("找到了,TA的名字是:%s", s);
else
printf("找不到!");
*/
// 插入新结点
p = (STU*) malloc (sizeof(STU));
p->num = 10002;
strcpy(p->name, "wanger");
p->grades[0] = 70;
p->grades[1] = 71;
p->grades[2] = 72;
p->grades[3] = 70;
p->grades[4] = 70;
p->next = NULL;
insert_node(head, p);
printf("插入后的链表数据:\n");
print_list(head);
/*
// 删除10002结点
delete_note(head, 10002);
printf("删除后的链表数据:\n");
print_list(head);
*/
calc_average(head);
printf("计算平均值后的链表数据:\n");
print_list(head);
return 0;
}
void append_node(STU *head)
{
STU *p, *q = head;
int num;
printf("请输入学号(小于或等于0则结束输入)");
scanf ("%d", &num);
while (num > 0)
{
p = (STU *) malloc (sizeof(STU));
// 输入数据
p->num = num;
printf("请输入姓名:");
scanf("%s", p->name);
printf("请输入5门课的成绩(以空格分隔):");
for (int i = 0; i < 5; i++)
scanf("%f", &p->grades[i]);
p->next = NULL;
// 建立关联
q->next = p;
q = p;
// 继续输入下一个num
printf("请输入学号(小于或等于0则结束输入)");
scanf("%d", &num) ;
}
}
void print_list(STU* head)
{
STU* p;
// 遍历(访问)链表数据
p = head->next;
printf("===========================\n");
printf("学号\t姓名\t成绩\t平均成绩\n");
printf("----------------------------\n");
while (p != NULL)
{
printf("%d\t%s\t%.1f\t%.2f\n",
p->num, p->name, p->grades[0], p->ave
);
p = p->next; // 意义上等同于p++
}
printf("===========================\n");
}
char* search_list(STU *head, int num) // 查找链表中某个元素是否存在
{
STU *p;
p = head->next;
while (p != NULL)
{
if (p->num == num)
{
return p->name;
} else {
p = p->next;
}
}
return NULL; // 没找到
}
void insert_node(STU *head, STU* p) // 向链表中插入一个结点
{
STU *q, *r;
r = head; q = r->next;
while (q != NULL)
{
if (p->num > q->num) // 继续往后移动
{
r = r->next; q = q->next;
} else { // 找到了位置,准备插入结点
r->next = p; p->next = q;
break;
}
}
if (q == NULL) // head之后无结点
{
r->next = p;
}
}
/*
* 删除链表中指定学号的结点
* @head 链表的头结点
* @num 要删除的学号
*/
void delete_note(STU *head, int num)
{
STU *p, *q;
q = head; p = head->next;
while (p != NULL && p->num != num)
{
p = p->next; q = q->next;
}
if (p != NULL) // 如果p不为NULL,则说明找到了
// ,删除结点
{
q->next = p->next;
free(p); // 释放p结点的空间
}
}
void calc_average(STU *head)
{
STU *p; float sum;
int i;
p = head->next;
while (p != NULL)
{
for (sum = 0, i = 0; i < 5; i++)
{
sum += p->grades[i];
}
p->ave = sum / 5;
p = p->next;
}
}