任务描述
本关任务:给定一个含有n个学生数据元素的数组a,用头插法来快速创建整个单链表。
相关知识
创建单链表有两种方法:
- 先初始化一个单链表,然后向其中一个一个地插入元素,通过调用基本运算算法来创建单链表。
- 还可以快速创建整个单链表,称为整体建表。整体建表常用方法有两种:头插法和尾插法。
头插法是将新增结点插入在头结点之后,单链表头插法创建过程示意图如下:

头插法创建单链表的算法思想:
- 从一个空单链表(含有一个L指向的头结点)开始,读取数组a(含有n个元素)中的一个元素,生成一个新结点p,将读取的数据元素存放到新结点的数据域中。
- 将新结点p插入到当前链表的表头后。
- 再读取数组a的下一个元素,采用相同的操作建立新结点p并插入到单链表L中,直到数组a中所有元素读完为止。
注意:头插法创建的单链表L中数据结点的次序与数组a的元素次序正好相反。
定义学生数据类型及输入、输出函数如下:
typedef struct date
{
int year;
int month;
int day;
}DATE;
typedef struct student
{
int num;
char name[20];
char sex;
DATE birthday;
float score;
}STUDENT;
typedef STUDENT ElemType;
void input(ElemType &s);
void output(ElemType s);单链表结点类型定义如下:
typedef struct LNode // 结点类型定义
{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList; // LinkList为结构指针类型测试说明
平台会对你编写的代码进行测试。
测试输入:
5
10010
Liyi
M
2000 5 23
45
10020
Lier
M
2001 2 3
62.5
10030
Lisan
F
2000 10 14
92.5
10040
Lisi
F
2002 7 23
87
10050
Liwu
M
1999 8 6
78
输入说明: 第一行输入为学生的个数N; 第二行开始输入N个学生的具体信息。
预期输出:
学号:10050 姓名:Liwu 性别:M 出生日期:1999-8-6 成绩:78.0
学号:10040 姓名:Lisi 性别:F 出生日期:2002-7-23 成绩:87.0
学号:10030 姓名:Lisan 性别:F 出生日期:2000-10-14 成绩:92.5
学号:10020 姓名:Lier 性别:M 出生日期:2001-2-3 成绩:62.5
学号:10010 姓名:Liyi 性别:M 出生日期:2000-5-23 成绩:45.0
输出说明: 输出为学生数据创建的单链表;每行输出一个学生的信息,输出数据的次序与输入次序正好相反。
这是我的答案1:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct date{
	int year;
	int month;
	int day;
}DATE;
typedef struct student{
	int num;
	char name[20];
	char sex;
	DATE birthday;
	float score;
}STUDENT;
typedef STUDENT ElemType;
void input(ElemType &s);
void output(ElemType s);
typedef struct LNnode{
	ElemType data;
	struct LNnode *next;
}LNnode,*LinkList;
void CreateHeadList(LinkList &L,ElemType a[],int n);//根据数组使用头插法创建单链表
void InitList(LinkList &L); 
void ListTraverse(LinkList L,void(*vi)(ElemType));
int main(){
	int n;
	LinkList head;
	ElemType a[100];
	scanf("%d",&n);
	for(int i = 0;i<n;i++){
		input(a[i]);
	}
	CreateHeadList(head,a,n);
	ListTraverse(head,output);
	return 0;
} 
void input(ElemType &s){
	scanf("%d",&(s.num));
	scanf("%s",s.name);
	scanf(" %c",&(s.sex));//注意这里加了一个空格
	scanf("%d%d%d",&(s.birthday.year),&(s.birthday.month),&(s.birthday.day));
	scanf("%f",&(s.score));
}
void output(ElemType s){
	printf("学号:%d\t姓名:%s\t性别:%c\t",s.num,s.name,s.sex);
	printf("出生日期:%d-%d-%d\t成绩:%.1f\n",s.birthday.year,s.birthday.month,s.birthday.day,s.score);
}
void InitList(LinkList &L){
	L = new LNnode;
	L->next = NULL;
}
void ListTraverse(LinkList L,void(*vi)(ElemType)){
	LinkList p  = L->next;
	while(p){
		vi(p->data);
		p = p->next;
	}
	printf("\n");
}
void CreateHeadList(LinkList &L,ElemType a[],int n){
	InitList(L);
	for(int i = 0;i<n;i++){
		ElemType e = a[i];
		LNnode *A = new LNnode;
		A->data = e;
		A->next = NULL;
	
		A->next = L->next;
		L->next = A;
	}
}

scanf输入字符,前面加了空格没有出现任何问题。现在演示不接空格的情况
scanf("%c",&(s.sex));
看到没结果变得杂乱无章。



















