任务描述
本关任务:给定一个含有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));
看到没结果变得杂乱无章。