数据结构实验01线性表.docx

上传人:b****6 文档编号:8609607 上传时间:2023-02-01 格式:DOCX 页数:16 大小:180.29KB
下载 相关 举报
数据结构实验01线性表.docx_第1页
第1页 / 共16页
数据结构实验01线性表.docx_第2页
第2页 / 共16页
数据结构实验01线性表.docx_第3页
第3页 / 共16页
数据结构实验01线性表.docx_第4页
第4页 / 共16页
数据结构实验01线性表.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

数据结构实验01线性表.docx

《数据结构实验01线性表.docx》由会员分享,可在线阅读,更多相关《数据结构实验01线性表.docx(16页珍藏版)》请在冰豆网上搜索。

数据结构实验01线性表.docx

数据结构实验01线性表

《数据结构与算法》实验报告

班级学号

姓名

实验周次

实验日期

实验01:

线性表

一、实验目的

1.掌握单向链表和顺序表的特点;

2.掌握链式和顺序存储结构的基本运算;

3.掌握单向链表和顺序表的创建、插入、删除和显示表中元素等基本操作。

二、实验内容

假设一个班有N个学生(N<20),每个学生有学号、姓名、性别、分数共4个成员。

各个学生之间的逻辑关系是线性的,请采用单向链表或顺序表作为存储结构编写程序。

程序所要实现的功能如下:

①插入一个学生到线性表的指定位置,如果用户指定位置不合法,则需给出相应提示;

②按学号从线性表中查找并删除一个指定学生,如果用户指定学生不存在,则需给出提示;

③按学号查找用户指定的某个学生,找到后更改该学生的指定信息,如果未找到该学生则需给出提示;

④输出所有学生的相关信息。

程序运行的主菜单如图1-1所示。

三、实验要求

1.学号为1-20号且学号为单号的同学:

以有头结点的单向链表作为线性表的存储结构;

2.学号为21-50号且学号为单号的同学:

以无头结点的单向链表作为线性表的存储结构。

3.所有学号为双号的同学:

采用顺序表作为线性表的存储结构,线性表的预设长度为20。

4.学有余力的同学:

采用顺序表作为线性表的存储结构,但是程序可以通过realloc()函数动态扩充顺序表的长度。

四、运行结果(截图)

图1-1显示表中所有信息

图1-2插入功能

图1-3删除功能

图1-4修改功能

图1-5修改结果的显示

五、实验程序(源代码)

#include"stdio.h"

#include"stdlib.h"

#include"string.h"

//学生结构体

typedefstruct

{

charno[10];

charname[20];

chargender;

floatscore;

}STU;

//单链表结点的结构体

typedefstructLNode

{

STUdata;//当前结点中存储的学生数据

structLNode*next;//下一个结点的地址

}LinkedNode;

//功能菜单

voidmenu()

{

printf("\n\t***********单向链表(无头结点)*************\n");

printf("\t*1插入一个学生*\n");

printf("\t*2删除一个学生*\n");

printf("\t*3修改学生信息*\n");

printf("\t*4输出所有学生信息*\n");

printf("\t*0保存数据并退出程序*\n");

printf("\t******************************************\n");

printf("\t请选择菜单项:

");

}

/*检测当前目录下是否存在文件stu.dat,如果存在,则从其中读取数据构造线性表;

否则,新建该数据文件。

*/

LinkedNode*init()

{

FILE*fp;

charflag='r';

STUstmp;

LinkedNode*head,*p,*rear;

//不带头结点的单链表,设置其头指针为空,则表示链表为空

head=NULL;

//打开文件

if((fp=fopen("stu.dat","rb"))==NULL)

{

flag='w';

if((fp=fopen("stu.dat","wb"))==NULL)

{

printf("数据文件不存在或创建文件不成功,程序异常退出!

\n");

exit(-1);

}

}

//开始读文件

if(flag=='r')

{

fread(&stmp,sizeof(STU),1,fp);

while(!

feof(fp))

{

//开辟一个结点空间

p=(LinkedNode*)malloc(sizeof(LinkedNode));

//构造结点

p->data=stmp;

p->next=NULL;

//为了保证恢复出来的链表结点顺序和当初存入的结点顺序保持一致

//将构造好的结点从尾部插入单向链表

if(NULL==head)//如果插入的是第一个结点

{

rear=p;

head=p;

}

else//如果插入的不是第一个结点

{

rear->next=p;

rear=p;

}

//再读一个学生的数据

fread(&stmp,sizeof(STU),1,fp);

}

}

//关闭文件

fclose(fp);

//返回单链表的头指针

returnhead;

}

/*输入一个学生的信息,构造一个新结点*/

LinkedNode*getNewNode()

{

LinkedNode*pNew;

//开辟一个结点空间

pNew=(LinkedNode*)malloc(sizeof(LinkedNode));

//构造结点

printf("请输入待插入学生的信息!

\n");

fflush(stdin);

printf("Pleaseinputthenum:

\t");

gets(pNew->data.no);

fflush(stdin);

printf("Pleaseinputthename:

\t");

gets(pNew->data.name);

fflush(stdin);

printf("Pleaseinputthesex:

\t");

scanf("%c",&(pNew->data.gender));

fflush(stdin);

printf("Pleaseinputthescore:

\t");

scanf("%f",&(pNew->data.score));

pNew->next=NULL;

returnpNew;

}

/*插入一个学生到不带头结点的单链表中*/

voidinsert(LinkedNode*&head)//调用过程中head有可能被改变,因此需用指针的引用参数,或者使用二级指针

{

intpoi,count;

LinkedNode*pre,*pNew;//pre指向插入位置的直接前驱结点,pNew用于开辟新结点空间

printf("请输入待插入学生的位置:

\n");

scanf("%d",&poi);

if(1==poi)//如果插入到第一个位置(此时需要改变head的值,因此需要单独讨论)

{

pNew=getNewNode();

//插入新结点到单向链表中的第一个结点之前

pNew->next=head;

head=pNew;//新结点成为新的第一个学生结点

}

else//如果插入的不是第一个位置

{

pre=head;//先让pre指向第一个学生结点

count=1;//第一个结点的报数为1

//当未到链表尾部,并且报数未到第poi-1个学生结点(即插入点的直接前驱)时

while(pre!

=NULL&&count

{

pre=pre->next;

count++;

}

//如果找到了正确的插入位置

if(count==poi-1&&pre!

=NULL)

{

pNew=getNewNode();//输入插入学生信息,构造一个新的结点

//插入新结点到单向链表中pre所指结点之后

pNew->next=pre->next;

pre->next=pNew;

}

else//如果插入位置不合法

{

printf("您输入的插入位置不合法!

\n");

}

}

}

/*从不带头结点的单链表中删除一个指定学生*/

voiddel(LinkedNode*&head)//调用过程中head有可能被改变,因此需用指针的引用参数,或者使用二级指针

{

if(NULL!

=head)

{

charno[10];

intflag=0;//flag==0表示未删除;flag==1表示已经删除

LinkedNode*pre,*q;//pre指向待删除结点的直接前驱,q指向待删除结点

fflush(stdin);

printf("请输入待删除学生的学号:

\n");

scanf("%s",no);

if(!

strcmp(head->data.no,no))//如果待删除的结点是第一个结点

{

q=head;

head=head->next;

printf("学号为%s的学生已经成功删除!

\n",q->data.no);

free(q);//先提示,后释放

flag=1;

}

else//如果待删除的结点不是第一个结点

{

//pre始终要指向待删除结点的直接前驱,先让其指向整个链表中的第一个学生结点

pre=head;

while(NULL!

=pre->next)

{

if(!

strcmp(pre->next->data.no,no))//如果找到了待删除结点的直接前驱

{

q=pre->next;//q指向待删除结点

pre->next=q->next;//先让q所指结点从链表中断开

printf("学号为%s的学生已经成功删除!

\n",q->data.no);

free(q);//先提示,后释放

flag=1;

break;

}

else

pre=pre->next;

}

}

if(0==flag)

printf("未找到您要删除的学生!

\n");

}

else

{

printf("当前单链表为空,没有学生数据可供删除!

\n");

}

}

/*查找指定学生,并修改其信息*/

voidmodify(LinkedNode*&head)//调用过程中head有可能被改变,因此需用指针的引用参数,或者使用二级指针

{

if(NULL!

=head)

{

charno[10];

intchoice,flag=0;

LinkedNode*p;

//p最终要指向待修改的学生结点,所以先让其指向第一个学生结点

p=head;

printf("请输入待修改学生的学号:

\n");

scanf("%s",no);

while(p!

=NULL)

{

if(!

strcmp(p->data.no,no))//如果找到待修改的学生

{

while

(1)

{

printf("当前学生的信息如下:

\n");

printf("1--学号:

%s\n",p->data.no);

printf("2--姓名:

%s\n",p->data.name);

printf("3--性别:

%c\n",p->data.gender);

printf("4--分数:

%.1f\n",p->data.score);

printf("请选择修改信息项的编号(输入0完成修改):

");

fflush(stdin);

scanf("%d",&choice);

switch(choice)

{

case1:

fflush(stdin);

printf("请输入修改后的学号:

");

scanf("%s",p->data.no);

break;

case2:

fflush(stdin);

printf("请输入修改后的姓名:

");

scanf("%s",p->data.name);

break;

case3:

fflush(stdin);

printf("请输入修改后的性别:

");

scanf("%c",&p->data.gender);

break;

case4:

fflush(stdin);

printf("请输入修改后的分数:

");

scanf("%f",&p->data.score);

break;

case0:

flag=1;//flag设置为1是为了跳出内层的while

(1)循环

break;

default:

printf("不存在此选项,请重新输入信息项的编号!

\n");

}

choice=-1;//输入错误的信息项编号或者未输入信息项编号

if(1==flag)

break;

}

return;//内层的while

(1)循环结束,说明修改完成,直接返回即可

}

else

p=p->next;//当前结点不是待修改的学生,继续查看链表中的下一个结点

}

//如果前面一直都未能通过return;语句返回,则说明链表中没有要找的学生

printf("当前单链表中没有学号为%s的学生!

\n",no);

}

else

{

printf("当前单链表为空,没有学生数据可供修改!

\n");

}

}

/*显示所有学生的信息*/

voidshowAll(LinkedNode*head)

{

LinkedNode*p;

inti;

//先让p指向第一个学生结点

p=head;

if(head)

{

printf("单链表中所有学生的信息如下!

\n");

printf("%5s%11s%21s%7s%9s\n","序号","学号","姓名","性别","成绩");

i=1;

while(NULL!

=p)

{

printf("%5d%11s%21s%7c%9.1f\n",i,p->data.no,p->data.name,p->data.gender,p->data.score);

p=p->next;

i++;

}

}

else

printf("单链表为空!

\n");

}

/*保存所有学生的信息到文件*/

voidsave(LinkedNode*head)

{

FILE*fp;

LinkedNode*p;

//打开文件

if((fp=fopen("stu.dat","wb"))==NULL)

{

printf("数据文件打开失败,保存不成功,程序异常退出!

");

exit(-1);

}

//开始写文件

p=head;

while(p!

=NULL)

{

fwrite(&(p->data),sizeof(STU),1,fp);

p=p->next;

}

//关闭文件

fclose(fp);

printf("单链表中的所有数据已经成功写入文件!

\n");

}

voidmain()

{

intchoice=-1;

LinkedNode*head;

head=init();

while

(1)

{

menu();

fflush(stdin);

scanf("%d",&choice);

switch(choice)

{

case1:

insert(head);

break;

case2:

del(head);

break;

case3:

modify(head);

break;

case4:

showAll(head);

break;

case0:

save(head);

exit(0);

break;

default:

printf("\t您输入的菜单项不存在,请重新选择!

\n");

}

choice=-1;

}

}

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1