实验03_单向链表
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验3 单项链表
【实验目的】
1.掌握单向链表的概念和建立方法。
2.掌握单向链表的基本操作。
【实验内容】
一.调试示例
输入若干个学生的信息(学号、姓名、成绩),当输入学号为0时结束,用单向链表组织这些学生信息后,再按顺序输出。
(源程序error11_3.cpp)
源程序(有错误的程序)
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 struct stud_node{
5 int num;
6 char name[20];
7 int score;
8 struct stud_node *next;
9 };
10 int main(void)
11 {
12 struct stud_node *head,*tail, *p;
13 int num, score;
14 char name[20];
15 int size = sizeof(struct stud_node);
16 head = tail = NULL;
17 printf("Input num,name and score:\n");
18 scanf("%d", &num);
19 /*建立单向链表*/
20 while(num != 0){
21 p = malloc(size);
22 scanf("%s%d", name, &score);
23 p->num = num;
24 strcpy(p->name, name);
25 p->score = score;
26 p->next = NULL;
27 tail->next = p;
28 tail = p;
29 scanf("%d", &num);
30 }
31 /*输出单向链表*/
32 for(p = head; p->next != NULL; p = p->next) /*调试时设置断点*/
33 printf("%d %s %d\n", p->num, p->name, p->score);
34 return 0;
35 }
运行结果(改正后程序的运行结果):
Input num,name and score:
1 zhang 78
2 wang 80
3 Li 75
4 zhao 85
1 zhang 78
2 wang 80
3 Li 75
4 zhao 85
1.编译后共有 1 errors,鼠标双击第一个错误,观察源程序中箭头指向第21 行,分析错误原因并改正:
错误信息:: error C2440: '=' : cannot convert from 'void *' to 'struct stud_node *' ;
错误原因:动态申请要指定其类型;
改正方法:在malloc前加上(struct stud_node*) ;
2.改正错误后重新编译、连接程序没有错误。
运行程序,当输入完第一行数据按回车后,出现出错信息。
错误信息:;
错误原因:在建立链表时没有考虑初始状态链表是空的情况;
改正方法:在第27行前插入语句:
if(head==NULL){head=p; tail = p;}else
;
3.改正错误后重新编译、运行程序,运行结果与预期不符之处为:
少了一行;
4.调试步骤:
(1)设置断点,具体位置见源程序的注释。
(2)单击(go)按钮,输入题目中给出的运行数据,程序运行到断点,在观察窗口中输入head,单击head前面的加号,就可以看到链表第一个结点的内容,再单击next前面的加号,就可以看到链表第二个结点的内容,以此类推(如图1所示)。
经查看,各元素值与输入的数据一致,说明链表建立正确。
(3)继续单步运行,同时观察输出窗口的信息。
发现当输出倒数第二个学生信息后for循环就结束了。
错误原因:最后一个学生的信息输出不了;
改正方法:32改for(p = head; p != NULL; p = p->next) ;
(4)单击(Stop Debugging )按钮,结束程序调试。
图1 链表调试
5.重新编译、连接、运行,运行结果与预期相符。
思考:
为什么要用动态内存分配方式建立链表结点?
省空间运算效率高
在链表结构中,next成员起什么作用?
记录下一个结构体的位置
二.改错题
输入若干个学生的学号(共7位,其中第2、3位是专业编号),以#作为输入结束标志,将其生成一个链表,统计链表中专业为计算机(编号为02)的学生人数。
(源程序error11_4.cpp)输入输出示例
1021202
2022310
8102134
1030912
3110203
4021205
#
3
源程序(有错误的程序)
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 struct node{
5 char code[8];
6 struct node *next;
7 };
8 int main(void)
9 {
10 struct node *head, *p;
11 int i, n, count;
12 char str[8];
13 int size = sizeof(struct node);
14 head = NULL;
15 gets(str);
16 /* 按输入数据的逆序建立链表*/
17 while(strcmp(str, ”#”) != 0){
18 p = (struct node *)malloc(size);
19 strcpy(p->code, str);
20 head = p->next;
21 head = p;
22 gets(str);
23 }
24 count = 0;
25 for(p = head; p->next != NULL; p = p->next)
26 if(p->(code[1]) == ’0’ && p->(code[2]) == ’2’)
27 count++ ;
28 printf(“%d\n”, count);
29 return 0;
30 }
1.编译后共有 3 errors,鼠标双击第一个错误,观察源程序中箭头位置,分析错误原因并改正:
错误信息:: error C2059: syntax error : '(' ;
错误原因:括号不用加;
改正方法:把26行中的code[]前后的括号去掉;
2.改正上述错误后,再次编译连接后无错误出现。
运行程序,输入测试数据。
运行出错情况:运行不了
对程序中的数据输入及链表建立过程进行单步调试,以查找错误。
查错过程:
错误原因:没有建立链表;
改正方法:删去20 21 加入
p->next =NULL;
if(head==NULL)
{ head=p;t=p;}
else{
t->next =p;t=p;}
t=p; 要在上面定义一个struct node *t ;
3.改正上述错误后,链表能够正确建立。
再次运行程序。
运行结果:没有是否正确:错误
对程序中的for循环部分进行单步调试,以查找错误。
查错过程:
错误原因:for(p = head; p->next != NULL; p = p->next) 错了;
改正方法:改为for(p = head; p!= NULL; p = p->next) ;
4.改正上述错误后,再次运行程序,运行结果正确。
改错汇总:
错误行号:26 正确语句:if(p->code[1] == ’0’ && p->code[2] == ’2’)
错误行号:25 正确语句:for(p = head; p!= NULL; p = p->next)
错误行号:20 21 正确语句:
p->next =NULL;
if(head==NULL)
{ head=p;t=p;}
else{
t->next =p;t=p;}
三.编程题
1.输入若干个学生信息(包括学号、姓名和成绩),输入学号为0时输入结束,建立一个单向链表,再输入一个成绩值,将成绩大于等于该值的学生信息输出。
输入输出示例
1 zhang 78
2 wang 80
3 Li 75
4 zhao 85
80
2 wang 80
4 zhao 85
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stud_node{
int num;
char name[20];
int score;
struct stud_node *next;
};
int main(void)
struct stud_node *head,*tail, *p;
int num, score;
char name[20];
int count;
int size = sizeof(struct stud_node);
head = tail = NULL;
printf("Input num,name and score:\n");
scanf("%d", &num);
while(num != 0){
p = (struct stud_node*)malloc(size);
scanf("%s%d", name, &score);
p->num = num;
strcpy(p->name, name);
p->score = score;
p->next = NULL;
if(head==NULL){head=p; tail = p;}else
tail->next = p;
tail = p;
scanf("%d", &num);
}
scanf("%d",&count);
for(p = head; p!= NULL; p = p->next) {
if(p->score>=count)
printf("%d %s %d\n", p->num, p->name, p->score); }
return 0;
}
2.输入若干个正整数(输入-1为结束标志),要求按输入数据的逆序建立一个链表,并输出。
输入输出示例
1 2 3 4 5 6 7 -1
7 6 5 4 3 2 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stud_node{
i nt num;
s truct stud_node *next;
};
struct stud_node *Creat_Stu_Doc();
void Ptrint_Stu_Doc(struct stud_node *head);
int main()
{
s truct stud_node *head,*ptr;
h ead=Creat_Stu_Doc();
i f(head==NULL){
printf("No Records\n");
for(ptr=head;ptr;ptr=ptr->next)
printf("%d ",ptr->num);
p rintf("\n");
}
struct stud_node *Creat_Stu_Doc()
{
s truct stud_node *head,*p;
i nt num;
i nt size=sizeof(struct stud_node);
h ead=NULL;
s canf("%d",&num);
w hile(num!=-1){
p=(struct stud_node *)malloc(size);
p->num=num;
p->next=head;
head=p;
scanf("%d",&num);
}
r eturn head;
}
3.输入若干个正整数(输入-1为结束标志),并建立一个单向链表,将其中的偶数值结点删除后输出。
输入输出示例
1 2 3 4 5 6 7 -1
1 3 5 7
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stud_node{
int num;
struct stud_node *next;
};
int main(void)
{
struct stud_node *head,*tail,*tempP,*frontP,*deleteP,*p,*t;
int num;
int count;
int size = sizeof(struct stud_node);
head = tail = NULL;
printf("输入数据\n");
scanf("%d", &num);
while(num!=-1){
p = (struct stud_node*)malloc(size);
p->num = num;
p->next = NULL;
if(head==NULL){head=p; tail = p;}else
tail->next = p;
tail = p;
scanf("%d", &num);
}
t empP=head;
w hile(tempP!=NULL)
{
if(0==tempP->num%2)
{
if(tempP==head)
{
head=tempP->next;
}
else
{
//找到偶数的前一个数,该数的next指向偶数的next;
for(frontP=head;NULL!=frontP;++frontP)
if(frontP->next==tempP)
{frontP->next=tempP->next;
break;
}
}
}
deleteP=tempP;
tempP=tempP->next;
if(deleteP->num%2==0)
delete deleteP;
}
t empP=head;
w hile(tempP!=NULL!)
{
printf("%d\n",tempP->num);
deleteP=tempP;
tempP=tempP->next;
delete deleteP;
}
}
4.输入若干个正整数(输入-1为结束标志)建立两个已按升序排序的单向链表,头指针分别为list1、list2,把两个链表拼成一个链表,并输出新链表信息。
要求自定义函数,实现将两个链表拼成一个链表,并返回拼组后的新链表。
输入输出示例
1 3 5 7 -1
2 4 6 -1
1 2 3 4 5 6 7
(下面我参考了网上的答案的)
#include<stdio.h>
#include<stdlib.h>
struct stud_node{
i nt num;
s truct stud_node *next;
};
struct stud_node *Creat_Stu_Doc();
void Ptrint_Stu_Doc(struct stud_node *head);
struct stud_node *InserDoc(struct stud_node *list1,struct stud_node *list2);
void main()
{
s truct stud_node *list1,*list2;
l ist1=Creat_Stu_Doc();
l ist2=Creat_Stu_Doc();
l ist1=InserDoc(list1,list2);
P trint_Stu_Doc(list1);
}
/****************************/
struct stud_node *Creat_Stu_Doc()
{
s truct stud_node *head,*tail,*p;
i nt num;
i nt size=sizeof(struct stud_node);
h ead=tail=NULL;
s canf("%d",&num);
w hile(num!=-1){
p=(struct stud_node *)malloc(size);
p->num=num;
p->next=NULL;
if(head==NULL)
head=p;
else
tail->next=p;
tail=p;
scanf("%d",&num);
}
r eturn head;
}
/***************************/
void Ptrint_Stu_Doc(struct stud_node *head) {
s truct stud_node *ptr;
i f(head==NULL){
printf("No Records\n");
return;
}
f or(ptr=head;ptr;ptr=ptr->next)
printf("%d ",ptr->num);
p rintf("\n");
/*******************************/
struct stud_node *InserDoc(struct stud_node *list1,struct stud_node *list2) {
s truct stud_node *ptr,*ptr1,*ptr2;
p tr2=list1;
p tr=list2;
w hile(list2!=NULL){
if(list1==NULL){
list1=ptr;
/* list1->next=NULL; ?*/
}
else{
while((ptr->num>ptr2->num)&&(ptr2->next!=NULL)){
ptr1=ptr2;
ptr2=ptr2->next;
}
if(ptr->num<=ptr2->num){
list2=list2->next;
if(list1==ptr2){
list1=ptr;
ptr1=ptr2;
}
else
ptr1->next=ptr;
ptr->next=ptr2;
ptr=list2;
ptr1=ptr1->next;
}
else{
ptr2->next=ptr;
break;
}
}
}
r eturn list1;
}
5.输入若干个正整数(输入-1为结束标志)建立一个单向链表,头指针为L,将链表L中奇数值的结点重新组成一个新的链表NEW,并输出新建链表的信息。
输入输出示例
1 2 3 4 5 6 7 -1
1 3 5 7
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stud_node{
i nt num;
s truct stud_node *next;
};
Int main()
{
s truct stud_node *L,*tail1,*tail2,*p1,*p2,*NEW,*ptr;
i nt num;
i nt size=sizeof(struct stud_node);
L=tail1=NULL;
s canf("%d",&num);
w hile(num!=-1){ /*---新建链表L--*/
p1=(struct stud_node *)malloc(size);
p1->num=num;
p1->next=NULL;
if(L==NULL)
L=p1;
else
tail1->next=p1;
tail1=p1;
scanf("%d",&num);
}
N EW=tail2=NULL;
p1=L;
while(p1!=NULL){
if(p1->num%2==0&&p1!=NULL){ /*--删除链表L中的偶数值---*/
if(p1->next!=NULL){
p1=p1->next;
continue;
}
else
break;
}
if(p1==NULL) break; /*----将链表L中奇数值的结点重新组成一个新的链表NEW--*/
p2=(struct stud_node *)malloc(size);
p2->num=p1->num;
p2->next=NULL;
if(NEW==NULL)
NEW=p2;
else
tail2->next=p2;
tail2=p2;
p1=p1->next;
}
t ail2->next=NULL;
I f(NEW==NULL)
printf("No Records\n");
for(ptr=head;ptr;ptr=ptr->next)
printf("%d ",ptr->num);
p rintf("\n");
}
【实验结果与分析】
将源程序、运行结果和分析以及实验中遇到的问题和解决问题的方法,写在实验报告上。