计算机课程
题 目
系 (部)
11 班 级
姓 名
学 号 2011222240 指导教师
数据结构 课 程 设 计 小型图
馆管理系统 电子与信息工程系
级计算机科学与技术 郭 小 龙 付 争 方
2013年01月08日
电子与信息工程系
《数据结构》课程设计任务书
2011222240 郭小龙
小型图书馆管理系统
郭小龙
安康学院 计算机科学与技术11级 陕西省 安康市 725000
摘要:
关键字:单链
;结构体;建立;指针;插入;查找;删除;排序。
1. 引言
线性表是数据结构的一个基本
。线性表的存储结构有顺序存储和链式存储结构,也就是我们常说的顺序表和链表。顺序和链式存储时线性表不同的存储方式,各有优劣,而不同的存储方式所对应的算法操作也不同,实现的效率也有差异。通过对两种存储方式进行对比分析,加深对链表的理解,
2. 链表的建立以及操作
2.1. 基本术语
(1)头节点
链表中的第一个节点,它没有存放有效地数据,只时使用了该节点的指针成员,指针成员指向了链表中的第一个有效节点的地址。
(2)首节点和尾节点
链表中的第一个存放有效数据的节点就是首节点,最后一个存放有效数据的节点。
(3)data域和next域
一个节点包括两个域,data域(数据域)用来存储节点的值,next 域(指针域)用来存放
存储数据元素的直接后继的地址。
2.2. 链表
链表即用一组地址任意的存储单元存放线性表中的数据元素,以元素和指针表示一个节点,是一种链式的存取的结构,为找第i个数据元素则必须找到第i-1个数据元素,所以查找第i个数据元素的基本操作为:移动指针比较i和j。
1
小型图书馆管理系统
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作比较。
2
2011222240 郭小龙
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.
3
小型图书馆管理系统
附件:
#include<stdio.h> #include<math.h> #include<string.h>
#include<stdlib.h> struct books_list {
char author[20]; /*作者名*/
char bookname[20]; /*书名*/ char publisher[20]; /*出版单位*/
char pbtime[15]; /*出版时间*/
char number[20]; /*书号*/ float price; /*价格*/ char classfy[10]; /*分类号*/
struct books_list * next; /*链表的指针域*/ };
struct books_list * Create_Books_Doc(); /*新建链表*/
void InsertDoc(struct books_list * head); /*插入*/
void DeleteDoc(struct books_list * head);/*删除*/
void Print_Book_Doc(struct books_list * head);/*浏览*/
void search_book(struct books_list * head); /*查询*/
void info_change(struct books_list * head);/*修改*/
4
void arrange(struct books_list * head);/*排序*/ void save(struct books_list * head);/*保存数据至文件*/
/*新建链表头节点*/
struct books_list * Create_Books_Doc() {
struct books_list * head;
head=(struct books_list *)malloc(sizeof(struct books_list)); /*分配头节点空间*/
head->next=NULL; /*头节点指针域初始化,定为空*/ return head; }
/*保存数据至文件*/
void save(struct books_list * head) {
struct books_list *p; FILE *fp; p=head;
fp=fopen("data.txt","w+"); /*以写方式新建并打开 data.txt文件*/
fprintf(fp,"???????????????????????????????????????\n"); /*向文件输出表格*/ fprintf(fp,"?书 号 ? 书 名 ? 作 者? 出版单位 ? 出版时间 ?分类号? 价格 ?\n");
fprintf(fp,"???????????????????????????????????????\n"); /*指针从头节点开始移动,遍历至尾结点,依次输出图书信息*/
2011222240 郭小龙
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->classf
y,p->price); }
fprintf(fp,"???????????????????????????????????????\n"); fclose(fp);
printf(" 已将图书数据保存到 data.txt 文件\n"); }
/*插入*/
void InsertDoc(struct books_list *head) {
/*定义结构体指针变量 s指向开辟的新结点首地址 p为中间变量*/ struct books_list *s,
*p; int n=0;
char flag=‘Y’; /*定义flag,方便用户选择重复输入*/ p=head;
/*遍历到尾结点,p指向尾结点*/ while(p->next!= NULL) {
p=p->next;n++; }
/*开辟新空间,存入数据,添加进链表*/ while(flag==‘Y’||flag==‘y’) {
s=(struct books_list *)malloc(sizeof(struct books_list));
printf("\n 请输入图书书号:"); fflush(stdin);
scanf("%s",s->number);
printf("\n 请输入图
5
书书名:"); 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;}
else if(flag==‘Y’||flag==‘y’) {continue;} }
save(head); /*保存数据至文件*/ return;
小型图书馆管理系统
}
/*查询操作*/
void search_book(struct books_list *head) {
struct books_list * p; char temp[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; }
/*浏览操作*/
void Print_Book_Doc(struct books_list * head) {
struct books_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->classf
y,p->price); /*循环输出表格*/ }
printf("?????????????????????????????????
??????\n");
6
2011222240 郭小龙
printf("\n"); }
/*修改操作*/
void info_change(struct books_list * head) {
struct books_list * p;
int panduan=0; /*此变量用于判断是否找到书目*/
char temp[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; }
/*删除操作*/
void DeleteDoc(struct books_list * head) {
struct books_list *s,*p; /*s为中间变量,p为遍历时使用的指针*/ char temp[20];
int panduan; /*此变量用于判断是否找到了书目*/
panduan=0; p=s=head;
printf(" [请输入您要删除的书名]:"); scanf("%s",temp);
/*遍历到尾结点*/ while(p!= NULL) {
if(strcmp(p->bookname,temp)==0) {
panduan++; break; }
7
小型图书馆管理系统
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; }
/*排序操作*/
void arrange(struct books_list * head) {
struct books_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 ;
8
else { while (p && p->next) { q = head;
/*查找插入位置*/
while (q->next->number < p->next->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; }
int main(void) {
struct books_list * head; char choice; head=NULL;
for(;;) /*实现反复输入选择*/ {
printf(" ?????????????????????????
\n");
printf(" ? ? socat 图书管理系统 ? ?
\n"); printf(" ? ???????????????????
?? ?\n");
printf(" ? ?[1]图书信息录入 ?
\n");
2011222240 郭小龙
printf(" ? ?
\n"); } printf(" ? else if(choice==‘2’)
{ ?[2]图书信息浏览 ?\n");
printf(" ? Print_Book_Doc(head);
?\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(" 请选择:");
fflush(stdin); scanf("%c",&choice); if(choice==‘1’) { if(head==NULL) { head=Create_Books_Doc(); } InsertDoc(head); }
else if(choice==‘3’)
{ search_book(head); } else if(choice==‘4’)
{ info_change(head); } else if(choice==‘5’)
{ InsertDoc(head); } else if(choice==‘6’)
{ DeleteDoc(head); } else if(choice==‘7’)
{ arrange(head); } else if(choice==‘8’)
{ printf("\n"); printf(" ???????? 感谢使用图书管理系统 ????????\n"); break;
} else { printf(" ???? 输入错误,请重新输入~????"); break; } } return 0; }
9
小型图书馆管理系统
流程图:
运行结果截图:
初始化界面 录入图书信息界面
10
2011222240 郭小龙
浏览所有图书界面
查询结构界面 修改图书信息界面
删除界面
插入界面
11
小型图书馆管理系统
排序界面
退出界面
12
2011222240 郭小龙
课程设计成绩评定表
13