题目如下所示
已知学生基本信息由学号(长整型)、姓名(字符数组)、性别(字符型)、年龄(整型)组成。定义如下结构类型:
// 定义结构体:存储学生基本信息
struct STUDENT_NODE {
long int id;
char name[MAX_LEN];
char sex;
int age;
// 指针指向下一个结点,用以形成链表
STUDENT_NODE *next;
};
//定义结构体:存储单向链表
struct STUDENT_LINK{
STUDENT_NODE *top;
};
应用上述结构类型,编程实现:建立一个结点按学号顺序存储学生信息的单向链表,并实现依据学号对链表的添加、修改、删除和检索功能;添加新结点后,应继续保持结点按学号顺序的链接方式。分别定义函数实现链表的初始化、链表的打印输出、以及在链表中添加、修改、删除和检索节点的功能;最后在main()中进行测试输出。
代码如下所示
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 50
// 定义结构体:存储学生基本信息
typedef struct STUDENT_NODE {
long int id;
char name[MAX_LEN];
char sex;
int age;
// 指针指向下一个结点,用以形成链表
struct STUDENT_NODE *next;
}STUDENT_NODE;
//定义结构体:存储单向链表
typedef struct STUDENT_LINK{
STUDENT_NODE *top;
}STUDENT_LINK;
void iniStudentLink(STUDENT_LINK * L); //初始化学生链表
void clearStudentLink(STUDENT_LINK * L);//清空学生链表
int isExist(STUDENT_LINK * L, long int id); //判断该学号的学生信息是否存在
int Add(STUDENT_LINK * L,long int id,char name[],char sex, int age); //添加一个新同学的信息
void ShowALL(STUDENT_LINK * L); // 从头到尾,输出当前所有的同学信息
int Modify(STUDENT_LINK * L, long int id,char name[],char sex, int age); // 根据学号,修改该同学的信息
int Delete(STUDENT_LINK * L, long int id); // 根据学号,从链表中删除该同学的信息
int Search(STUDENT_LINK * L,long int id); // 根据学号,输出显示该同学信息
int main(){
STUDENT_LINK * L;
long int id;
char name[MAX_LEN];
char sex;
int age;
iniStudentLink(L);//初始化学生链表
ShowALL(L);//从头到尾,输出当前所有的同学信息
/*添加一个新同学的信息*/
printf("\n以下尝试添加一个新同学的信息\n");
printf("学号:");
scanf("%ld", &id);
printf("姓名:");
scanf("%s", &name);
getchar();
printf("性别(女为w男为m):");
scanf("%c", &sex);
printf("年龄:");
scanf("%d", &age);
Add(L, id, name, sex, age);
ShowALL(L);//从头到尾,输出当前所有的同学信息
/*修改一个同学的信息 */
printf("\n以下尝试修改一个同学的信息\n");
printf("学号:");
scanf("%ld", &id);
printf("姓名:");
scanf("%s", &name);
getchar();
printf("性别(女为w男为m):");
scanf("%c", &sex);
printf("年龄:");
scanf("%d", &age);
Modify(L, id, name, sex, age);
ShowALL(L);//从头到尾,输出当前所有的同学信息
/*显示一个同学的信息*/
printf("\n请输入想要显示信息的同学学号:\n");
scanf("%ld", &id);
Search(L, id);
/*删除一个同学的信息*/
printf("\n请输入想要删除信息的同学学号:\n");
scanf("%ld", &id);
Delete(L, id);
ShowALL(L);//从头到尾,输出当前所有的同学信息
clearStudentLink(L);//清空学生链表
return 0;
}
void iniStudentLink(STUDENT_LINK * L){//初始化学生链表
int n,i;
printf("请初始化学生数量:");
scanf("%d", &n);
STUDENT_NODE *head = NULL;//初始化头指针为空
for(i=0; i<n; i++){
//申请一块空间存储当前学生的信息
STUDENT_NODE *p = (STUDENT_NODE*)malloc(sizeof(STUDENT_NODE));
printf("请输入第%d个学生信息\n", i+1);
printf("学号:");
scanf("%ld", &p->id);
printf("姓名:");
scanf("%s", &p->name);
getchar();
printf("性别(女为w男为m):");
scanf("%c", &p->sex);
printf("年龄:");
scanf("%d", &p->age);
p->next = NULL;
STUDENT_NODE *last = head;//使末指针初始化等同于头指针
if(last){//如果末指针不为空
while(last->next){//找到链表末尾
last = last->next;
}
last->next = p;//将新结点链在末尾处
}
else{//如果末指针为空
head = p;//使头指针指向当前空间
}
}
//下面对该链表按学号由小到大排序
STUDENT_NODE *pre, *a;
pre = head;//一开始指向头部
while (pre->next != NULL)
{
a = pre->next;//a指向pre的下一个节点
while (a != NULL)
{
if (pre->id > a->id)//如果本轮最前端的学号大于于此节点中的学号
{
//互换他们的学号和各项信息
int n = pre->id;
char na[MAX_LEN];
strcpy(na, pre->name);
char se = pre->sex;
int ag = pre->age;
pre->id = a->id;
strcpy(pre->name, a->name);
pre->sex = a->sex;
pre->age = a->age;
a->id = n;
strcpy(a->name, na);
a->sex = se;
a->age = ag;
}
a = a->next;//使a指向下一个节点
}
pre = pre->next;//使pre指向下一个节点
}
L->top = head;
}
void clearStudentLink(STUDENT_LINK * L){//清空学生链表
STUDENT_NODE *p, *q;
for(p=L->top; p; p=q){//遍历整个链表
q = p->next;
free(p);//释放当前结点
}
}
int isExist(STUDENT_LINK * L, long int id){//判断该学号的学生信息是否存在
STUDENT_NODE *p, *q;
int flag = 0;
for(p=L->top; p; p=q){//遍历整个链表
q = p->next;
if(p->id == id){
flag = 1;
break;
}
}
return flag;
}
int Add(STUDENT_LINK * L,long int id,char name[],char sex, int age){//添加一个新同学的信息
if(isExist(L, id)){
printf("已有该同学的信息!\n");
}
else{
//申请一块新的空间,把该同学的各项信息存进去
STUDENT_NODE *p = (STUDENT_NODE*)malloc(sizeof(STUDENT_NODE));
p->id = id;
p->sex = sex;
p->age = age;
strcpy(p->name, name);
STUDENT_NODE *r, *q;
int flag = 0;
for(r=L->top; r; r=q){//遍历整个链表
q = r->next;
if(r == L->top){//如果当前为链表头部
if(r->id > p->id){
L->top = p;
p->next = r;
break;
}
}
if(q != NULL){//如果没到链表末尾
if(q->id > p->id){//如果下一位同学的学号大于新同学的学号
r->next = p;//将新同学结点链在当前同学后
p->next = q;
break;
}
}
else{
r->next = p;
p->next = NULL;
}
}
printf("成功添加学生信息!\n");
}
}
void ShowALL(STUDENT_LINK * L){//从头到尾,输出当前所有的同学信息
STUDENT_NODE *p, *q;
printf("\n所有同学的各项信息如下:\n");
for(p=L->top; p; p=q){//遍历整个链表
q = p->next;
printf("学号:%ld 姓名:%s 性别:%c 年龄:%d\n",p->id,p->name,p->sex,p->age);
}
}
int Modify(STUDENT_LINK * L, long int id,char name[],char sex, int age){//根据学号,修改该同学的信息
STUDENT_NODE *p, *q;
for(p=L->top; p; p=q){//遍历整个链表
q = p->next;
if(p->id == id){
strcpy(p->name, name);
p->sex = sex;
p->age = age;
printf("\n修改成功!\n");
return 1;
}
}
printf("没有该同学的信息!\n");
return 0;
}
int Delete(STUDENT_LINK * L, long int id){ // 根据学号,从链表中删除该同学的信息
STUDENT_NODE *p, *q, *r;
for(p=L->top; p; r=p, p=q){//遍历整个链表
q = p->next;
if(p == L->top){//如果当前为链表头部
if(p->id == id){
L->top = q;
free(p);
printf("删除成功!\n");
return 1;
}
}
else{
if(p->id == id){
r->next = q;
free(p);
printf("删除成功!\n");
return 1;
}
}
;
}
printf("没有该同学的信息!\n");
return 0;
}
int Search(STUDENT_LINK * L,long int id){// 根据学号,输出显示该同学信息
STUDENT_NODE *p, *q;
for(p=L->top; p; q=p->next, p=q){//遍历整个链表
if(p->id == id){
printf("\n输出该同学的信息如下所示\n");
printf("学号:%ld 姓名:%s 性别:%c 年龄:%d\n",p->id,p->name,p->sex,p->age);
return 1;
}
}
printf("没有该同学的信息!\n");
return 0;
}