计算机课程设计.docx
《计算机课程设计.docx》由会员分享,可在线阅读,更多相关《计算机课程设计.docx(24页珍藏版)》请在冰豆网上搜索。
计算机课程设计
数据结构课程设计
题目小型图书馆管理系统
系(部)电子与信息工程系
班级11级计算机科学与技术
姓名郭小龙
学号2011222240
指导教师付争方
2013年01月08日
电子与信息工程系
《数据结构》课程设计任务书
设计题目
小型图书馆管理系统(链表的插入,排序,查询,删除)
已知技术参数和设计要求
对C语言软件开发有一定的认识,了解并掌握开发的各个流程,以及各功能代码的实现。
创建一个图书馆管理系统,可进行还书(插入),排序,查找,借书(删除)操作。
【设计原理】
1.所有信息存储在一个带头结点的单向链表中,每个结点存储一条图书记录,即结构体(book),其中各域为:
书号(number)、书名(title)、作者(writer)、定价(pricing)、出版社(publishinghouse),指针域(next)。
2.系统初始时图书记录为空,由用户录入信息,进行插入(包括创建),排序,查找,删除操作。
3.有两种排序算法可选:
选择排序和直接插入排序,均由链表实现。
4.如输入有错,给出出错提示。
设计内容与步骤
1、结点结构的设计
2、算法设计与分析
3、程序设计、实现、调试
4、课程设计说明书
设计工作计划与进度安排
1、设计工作4学时
2、实现与调试16学时
3、课程设计说明书8学时
设计考核要求
1、考勤30%
2、课程设计说明书70%
计算机教研室制
小型图书馆管理系统
郭小龙
安康学院计算机科学与技术11级陕西省安康市725000
摘要:
本文采用单链表,通过对链表的技术的探究,利用C语言实现了从程序打开新建文件并写入内容,并进行插入、查找、删除、排序的功能,同时克服了C语言下数组长度的有限性。
经实验验证,效果良好。
关键字:
单链表;结构体;建立;指针;插入;查找;删除;排序。
1.引言
线性表是数据结构的一个基本内容。
线性表的存储结构有顺序存储和链式存储结构,也就是我们常说的顺序表和链表。
顺序和链式存储时线性表不同的存储方式,各有优劣,而不同的存储方式所对应的算法操作也不同,实现的效率也有差异。
通过对两种存储方式进行对比分析,加深对链表的理解,本文分析了数据结构中链表的建立,插入,查找,删除,排序运算的实现并给出相应的程序。
使人们对链表的优缺点有一个明确的认识。
2.链表的建立以及操作
2.1.基本术语
(1)头节点
链表中的第一个节点,它没有存放有效地数据,只时使用了该节点的指针成员,指针成员指向了链表中的第一个有效节点的地址。
(2)首节点和尾节点
链表中的第一个存放有效数据的节点就是首节点,最后一个存放有效数据的节点。
(3)data域和next域
一个节点包括两个域,data域(数据域)用来存储节点的值,next域(指针域)用来存放存储数据元素的直接后继的地址。
2.2.链表
链表即用一组地址任意的存储单元存放线性表中的数据元素,以元素和指针表示一个节点,是一种链式的存取的结构,为找第i个数据元素则必须找到第i-1个数据元素,所以查找第i个数据元素的基本操作为:
移动指针比较i和j。
2.3.链表的建立和基本操作
链表的建立需要使用标准malloc(size)函数来为其申请一个长度为size字节的连续空间,建立时有头插法和尾插法两种方法。
基本操作包括链表的插入、查找、删除、排序。
3.链表的建立和操作的算法描述
3.1.链表的建立
单链表的建立有头插法、尾插法两种方法。
(1)头插法
单链表是用户不断申请存储单元和改变链接关系而得到的一种特殊数据结构,将链表的左边称为链头,右边称为链尾。
头插法建单链表是将链表右端看成固定的,链表不断向左延伸而得到的。
头插法最先得到的是尾结点。
由于链表的长度是随机的,故用一个while循环来控制链表中结点个数。
假设每个结点的值都大于O,则循环条件为输入的值大于o。
申请存储空间可使用malloc()函数实现,需设立一申请单元,但malloc()函数得到的指针并不是指向结构体的指针,需使用强制类型转换,将其转换成结构体型指针。
刚开始时,链表还没建立,是一空链表,head指针为NULL。
链表建立的过程是申请空间、得到数据、建立链接的循环处理过程。
(2)尾插法
若将链表的左端固定,链表不断向右延伸,这种建立链表的方法称为尾插法。
尾插法建立链表时,头指针固定不动,故必须设立一个搜索指针,向链表右边延伸,则整个算法中应设立三个链表指针,即头指针head、搜索指针p2、申请单元指针pl。
尾插法最先得到的是头节点。
3.2.基本操作的算法(插入、查找、删除、排序)
3.2.1.插入
插入运算是将值为x的新结点插入到表的第i个结点的位置上,即插入到ai-1与ai之间。
(1)找到ai-1存储位置p
(2)生成一个数据域为x的新结点*s
(3)令结点*p的指针域指向新结点(4)新结点的指针域指向结点ai
3.2.2.查找(按值查找和按序号查找)
(1)按序号查找
设带头结点的单链表的长度为n,要查找表中第i个结点,则需要从单链表的头指针L出发,从头结点(H->next)开始顺着链表扫描,用指针p指向当前扫描到的结点,初值指向头结点,用j左计数器,累计当前扫描过的结点数(初值为0),当j=i时,指针所指结点就是要找的第i个结点。
(2)按值查找
按值查找是指在单链表中查找是否有结点值等于e的结点,若有的话,则返回首次找到的其值为e的结点的存储位置,否则返回NULL。
查找过程从单链表的头指针指向的头结点出发,顺着链逐个将结点的值和给定值e作比较。
3.2.3.删除(按值删除和按序号删除)
(1)按序号删除
与在带头结点的单链表L中删除第i个结点,则首先要通过计数方式找到第i-1个结点并使p指向第i-1个结点,而后删除第i个结点并释放结点空间。
(2)按值删除
在链表中删除节点值等于e的节点,则首先要通过指针的向后移动比较每个节点data域值与e是否相等,相等的话则将前一个节点的next指向这个节点的后一个节点,释放删除节点的空间。
3.2.4.排序
链表的排序可用很多的方法,比如选择排序和直接插入排序又或者冒泡排序。
排序是需要用节点的data域,比较其值得大小。
然后通过指针修改节点只链表中的位置。
4.结语
通过以上的探究,我们可以发现链表就像一条锁链一样,一环扣一环。
在操作中它要不断的进行遍历,从一个节点跳到下一个节点,然后修改它前后节点的指针。
并且在操作的节点距离首节点比较近的时候花费的时间是比较上的。
但是距离比较远是则显示了它的不足之处,所以我们在对一组数据操作时选用正确的存储方式是非常重要的。
参考文献:
耿国华.数据结构—用c语言描述[M].北京:
高等教育出版社,2005.
附件:
#include
#include
#include
#include
structbooks_list
{
charauthor[20];/*作者名*/
charbookname[20];/*书名*/
charpublisher[20];/*出版单位*/
charpbtime[15];/*出版时间*/
charnumber[20];/*书号*/
floatprice;/*价格*/
charclassfy[10];/*分类号*/
structbooks_list*next;/*链表的指针域*/
};
structbooks_list*Create_Books_Doc();/*新建链表*/
voidInsertDoc(structbooks_list*head);/*插入*/
voidDeleteDoc(structbooks_list*head);/*删除*/
voidPrint_Book_Doc(structbooks_list*head);/*浏览*/
voidsearch_book(structbooks_list*head);/*查询*/
voidinfo_change(structbooks_list*head);/*修改*/
voidarrange(structbooks_list*head);/*排序*/
voidsave(structbooks_list*head);/*保存数据至文件*/
/*新建链表头节点*/
structbooks_list*Create_Books_Doc()
{
structbooks_list*head;
head=(structbooks_list*)malloc(sizeof(structbooks_list));/*分配头节点空间*/
head->next=NULL;/*头节点指针域初始化,定为空*/
returnhead;
}
/*保存数据至文件*/
voidsave(structbooks_list*head)
{
structbooks_list*p;
FILE*fp;
p=head;
fp=fopen("data.txt","w+");/*以写方式新建并打开data.txt文件*/
fprintf(fp,"┏━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━━┳━━━┳━━━━┓\n");/*向文件输出表格*/
fprintf(fp,"┃书号┃书名┃作者┃出版单位┃出版时间┃分类号┃价格┃\n");
fprintf(fp,"┣━━━╋━━━━━╋━━━━━╋━━━━━╋━━━━━━╋━━━╋━━━━┫\n");
/*指针从头节点开始移动,遍历至尾结点,依次输出图书信息*/
while(p->next!
=NULL)
{
p=p->next;
fprintf(fp,"┃%-6.6s┃%-10.10s┃%-10.10s┃%-10.10s┃%-12.12s┃%-6.6s┃%.2f┃\n",p->number,p->bookname,p->author,p->publisher,p->pbtime,p->classfy,p->price);
}
fprintf(fp,"┗━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━━┻━━━┻━━━━┛\n");
fclose(fp);
printf("已将图书数据保存到data.txt文件\n");
}
/*插入*/
voidInsertDoc(structbooks_list*head)
{
/*定义结构体指针变量s指向开辟的新结点首地址p为中间变量*/
structbooks_list*s,*p;
intn=0;
charflag='Y';/*定义flag,方便用户选择重复输入*/
p=head;
/*遍历到尾结点,p指向尾结点*/
while(p->next!
=NULL)
{
p=p->next;n++;
}
/*开辟新空间,存入数据,添加进链表*/
while(flag=='Y'||flag=='y')
{
s=(structbooks_list*)malloc(sizeof(structbooks_list));
printf("\n请输入图书书号:
");
fflush(stdin);
scanf("%s",s->number);
printf("\n请输入图书书名:
");
fflush(stdin);
scanf("%s",s->bookname);
printf("\n请输入图书作者名:
");
fflush(stdin);
scanf("%s",s->author);
printf("\n请输入图书出版社:
");
fflush(stdin);
scanf("%s",s->publisher);
printf("\n请输入图书出版时间:
");
fflush(stdin);
scanf("%s",s->pbtime);
printf("\n请输入图书分类号:
");
fflush(stdin);
scanf("%s",s->classfy);
printf("\n请输入图书价格:
");
fflush(stdin);
scanf("%f",&s->price);
printf("\n");
p->next=s;/*将新增加的节点添加进链表*/
p=s;/*p指向尾节点,向后移*/
s->next=NULL;
printf("━━━━添加成功!
━━━━");
printf("\n继续添加?
(Y/N):
");
fflush(stdin);
scanf("%c",&flag);
printf("\n");
if(flag=='N'||flag=='n')
{break;}
elseif(flag=='Y'||flag=='y')
{continue;}
}
save(head);/*保存数据至文件*/
return;
}
/*查询操作*/
voidsearch_book(structbooks_list*head)
{
structbooks_list*p;
chartemp[20];
p=head;
if(head==NULL||head->next==NULL)/*判断数据库是否为空*/
{
printf("━━━━图书库为空!
━━━━\n");
}
else
{
printf("请输入您要查找的书名:
");
fflush(stdin);
scanf("%s",temp);
/*指针从头节点开始移动,遍历至尾结点,查找书目信息*/
while(p->next!
=NULL)
{
p=p->next;
if(strcmp(p->bookname,temp)==0)
{
printf("\n图书已找到!
\n");
printf("\n");
printf("书号:
%s\t\n",p->number);
printf("书名:
%s\t\n",p->bookname);
printf("作者名:
%s\t\n",p->author);
printf("出版单位:
%s\t\n",p->publisher);
printf("出版时间:
%s\t\n",p->pbtime);
printf("分类号:
%s\t\n",p->classfy);
printf("价格:
%.2f\t\n",p->price);
}
if(p->next==NULL)
{
printf("\n查询完毕!
\n");
}
}
}
return;
}
/*浏览操作*/
voidPrint_Book_Doc(structbooks_list*head)
{
structbooks_list*p;
if(head==NULL||head->next==NULL)/*判断数据库是否为空*/
{
printf("\n━━━━没有图书记录!
━━━━\n\n");
return;
}
p=head;
printf("┏━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━━┳━━━┳━━━━┓\n");
printf("┃书号┃书名┃作者┃出版单位┃出版时间┃分类号┃价格┃\n");
printf("┣━━━╋━━━━━╋━━━━━╋━━━━━╋━━━━━━╋━━━╋━━━━┫\n");
/*指针从头节点开始移动,遍历至尾结点,依次输出图书信息*/
while(p->next!
=NULL)
{
p=p->next;
printf("┃%-6.6s┃%-10.10s┃%-10.10s┃%-10.10s┃%-12.12s┃%-6.6s┃%.2f┃\n",p->number,p->bookname,p->author,p->publisher,p->pbtime,p->classfy,p->price);/*循环输出表格*/
}
printf("┗━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━━┻━━━┻━━━━┛\n");
printf("\n");
}
/*修改操作*/
voidinfo_change(structbooks_list*head)
{
structbooks_list*p;
intpanduan=0;/*此变量用于判断是否找到书目*/
chartemp[20];
p=head;
printf("请输入要修改的书名:
");
scanf("%s",temp);
while(p->next!
=NULL)
{
p=p->next;
if(strcmp(p->bookname,temp)==0)
{
printf("\n请输入图书书号:
");
fflush(stdin);
scanf("%s",p->number);
printf("\n请输入图书书名:
");
fflush(stdin);
scanf("%s",p->bookname);
printf("\n请输入图书作者名:
");
fflush(stdin);
scanf("%s",p->author);
printf("\n请输入图书出版社:
");
fflush(stdin);
scanf("%s",p->publisher);
printf("\n请输入图书出版时间:
");
fflush(stdin);
scanf("%s",p->pbtime);
printf("\n请输入图书分类号:
");
fflush(stdin);
scanf("%s",p->classfy);
printf("\n请输入图书价格:
");
fflush(stdin);
scanf("%f",&p->price);
printf("\n");
panduan=1;
}
}
if(panduan==0)
{
printf("\n━━━━没有图书记录!
━━━━\n\n");
}
save(head);/*保存数据至文件*/
return;
}
/*删除操作*/
voidDeleteDoc(structbooks_list*head)
{
structbooks_list*s,*p;/*s为中间变量,p为遍历时使用的指针*/
chartemp[20];
intpanduan;/*此变量用于判断是否找到了书目*/
panduan=0;
p=s=head;
printf("[请输入您要删除的书名]:
");
scanf("%s",temp);
/*遍历到尾结点*/
while(p!
=NULL)
{
if(strcmp(p->bookname,temp)==0)
{
panduan++;
break;
}
p=p->next;
}
if(panduan==1)
{
for(;s->next!
=p;)/*找到所需删除卡号结点的上一个结点*/
{
s=s->next;
}
s->next=p->next;/*将后一节点地址赋值给前一节点的指针域*/
free(p);
printf("\n━━━━删除成功!
━━━━\n");
}
else/*未找到相应书目*/
{
printf("您输入的书目不存在,请确认后输入!
\n");
}
save(head);/*保存数据至文件*/
return;
}
/*排序操作*/
voidarrange(structbooks_list*head)
{
structbooks_list*temp,*q,*p;
if(head==NULL||head->next==NULL)/*判断数据库是否为空*/
{
printf("\n━━━━没有图书记录!
━━━━\n\n");
return;
}
p=head->next;
q=head;
temp=NULL;
if(p->next==NULL)
return;
else
{
while(p&&p->next)
{
q=head;
/*查找插入位置*/
while(q->next->numbernext->number)
q=q->next;
/*如果要插入的位置不与原位置相同,则执行插入*/
if(q!
=p)
{
temp=p->next;
p->next=temp->next;
temp->next=q->next;
q->next=temp;
}
else
p=p->next;
}
}
save(head);/*保存数据至文件*/
return;
}
intmain(void)
{
structbooks_list*head;
charchoice;
head=NULL;
for(;;)/*实现反复输入选择*/
{
printf("┏━┓━━━━━━━━━━━━━━━━━━━┏━┓\n");
printf("┃┃socat图书管理系统┃┃\n");
printf("┃┗━━━━━━━━━━━━━━━━━━━┛┃\n");
printf("┃●[1]图书信息录入┃\n");
printf("┃┃\n");
printf("┃●[2]图书信息浏览┃\n");
printf("┃┃\n");
printf("┃●[3]图书信息查询┃\n");
printf("┃┃\n");
printf("┃●[4]图书信息修改┃\n");
printf("┃┃\n");
printf("┃●[5]图书信息插入┃\n");
printf("┃┃\n");
printf("┃●[6]图书信息删除┃\n");
printf("┃┃\n");
printf("┃●[7]图书信息排序┃\n");
printf("┃┃\n");
printf("┃●[8]退出系统┃\n");
printf("┗━━━━━━━━━━━━━━━━━━━━━━━┛\n");
printf("请选择:
");