图书信息管理系统
原文链接
本代码是为了实现数据结构书上的案例2.3。由于书中对于代码功能的描述太过简单,很难理解他到底具体的要求是什么,所以我只能根据自己的理解来实现查找,插入,删除,修改,排序和计数功能。为了方便查看我们的代码功能是否成功实现,我创建了一个可以输出整个单链表存储的图书信息的函数TraverseList(LinkList L);
。
结构体结构
对于图书的基本信息的存储,我们采用结构体来实现。由于书中只说了图书的基本信息包括ISBN,书名,定价,所以我们只需要存储这三条信息就行。我们的整个管理系统是采用单链表来存储全部图书信息。
typedef struct
{
char ISBN[20];
char name[20];
float price;
}Book;
typedef struct LNode
{
Book elem;
struct LNode *next;
}LNode, *LinkList;
功能选择
通过使用switch语句来选择不同的功能。1代表插入,2代表查询,3代表删除,4代表修改,5代表计数,6代表排序功能。
插入
只有我们通过在线性表中插入图书信息以后才能使用其他功能,所以我们先设计插入功能。对于图书管理程序,每当别人还了一本书,把这本书插入到这个系统即可。所以,我们的代码将直接在单链表末尾插入这个图书信息。
int Insert(LinkList L, Book e)
{
LNode *p;
p= L;
while(p->next)
{
p=p->next;
}
LNode *s;
s = (LNode *)malloc(sizeof(LNode));
s->elem = e;
s->next = p->next;
p->next= s;
return OK;
}
输出整个链表信息
通过遍历整个单链表,输出所有的图书信息。方便查看我们的查找,插入,删除,修改,排序和计数功能是否成功的实现。
int TraverseList(LinkList L)
{
LNode *p;
p=L->next;
while(p)
{
printf("ISBN:%s name:%s price:%f\n",p->elem.ISBN,p->elem.name,p->elem.price);
p = p->next;
}
return OK;
}
查找
查找功能实现的通过输入图书的书名,来查找单链表中是否有这本书。
int Serch(LinkList L,char *bookname)
{
LNode *p;
p = L->next;
while(p&& strcmp(p->elem.name,bookname)!=0)
{
p = p->next;
}
if(p==NULL)
{
printf("Can't find\n");
}
else
{
printf("have this book.\n");
}
return OK;
}
删除
通过输入图书的ISBN编号,删除单链表中这本图书的信息。如果没有这本书的话,直接输出Can’t find。
int Delete(LinkList L,char *ISBN)
{
LNode *p;
LNode *prior;
p= L->next;
while(p && strcmp(p->elem.ISBN,ISBN)!=0)
{
prior = p;
p = p->next;
}
if(p==NULL)
{
printf("Can't find\n");
}
else
{
prior->next = p->next;
printf("delete it\n");
}
return OK;
}
修改
通过输入图书的ISBN号码,然后输入新的图书名称和定价。代码会查找单链表中是否有输入的ISBN号码的这本图书,燃火把新的图书名称和定价改过去。
int Modify(LinkList L,char *ISBN,char *name,float price)
{
LNode *p;
p = L->next;
while(p&& strcmp(p->elem.ISBN,ISBN)!=0)
{
p = p->next;
}
if(p==NULL)
{
printf("Can't find\n");
}
else
{
strcpy(p->elem.name,name);
p->elem.price = price;
}
return OK;
}
计数
通过循环整个单链表,来查看整个链表有多少本图书。
int Count(LinkList L)
{
LNode *p;
int cnt = 0;
p = L->next;
while(p)
{
cnt++;
p = p->next;
}
return cnt;
}
排序
由于书中并没有说明到底根据什么排序,所以我是根据书的ISBN号码进行排序的。排序的方式是从小到大。
int bubbleSort(LinkList L)
{
if(L->next == NULL || L->next->next == NULL)
return OK; //如果链表是空的或者只有一个元素,直接返回
int flag = 0;
LNode *cur; //游标节点
LNode *pre; //游标节点的前驱节点
LNode *tail = NULL; //尾指针节点
LNode *temp; //临时节点
while(L->next != tail)
{
cur = L->next;
pre = L; //这样确保pre是cur前面的那个节点
while(cur->next != tail )
{
if(strcmp(cur->elem.ISBN,cur->next->elem.ISBN)>0) //这里是根据ISBN的大小进行排序
{
temp = cur->next;
cur->next = temp->next;
temp->next = cur;
pre->next = temp;
pre = temp;
flag = 1;
}
else
{
pre = pre->next;
cur=cur->next;
}
}
if(flag == 0)
return OK;
tail = cur; //使得每次循环结束后,最后一个节点就是最大的元素,尾节点往前挪一位
}
}
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERROR 0
typedef struct
{
char ISBN[20];
char name[20];
float price;
}Book;
typedef struct LNode
{
Book elem;
struct LNode *next;
}LNode, *LinkList;
int Insert(LinkList L, Book e);
int TraverseList(LinkList L);
int Serch(LinkList L,char *bookname);
int Delete(LinkList L,char *ISBN);
int Modify(LinkList L,char *ISBN,char *name,float price);
int Count(LinkList L);
int bubbleSort(LinkList L);
int main()
{
int sign;
int status;
LinkList L;
char ISBN[20],name[20];
float price;
Book e;
int cnt;
L = (LNode *)malloc(sizeof(LNode));
L->next = NULL;
while(scanf("%d",&sign)!=EOF)
{
switch (sign)
{
case 1:
scanf("%s %s %f",ISBN,name,&price);
strcpy(e.ISBN,ISBN);
strcpy(e.name,name);
e.price = price;
Insert(L,e);
TraverseList(L);
break;
case 2:
scanf("%s",name);
Serch(L,name);
break;
case 3:
scanf("%s",ISBN);
Delete(L,ISBN);
TraverseList(L);
break;
case 4:
scanf("%s %s %f",ISBN,name,&price);
Modify(L,ISBN,name,price);
TraverseList(L);
break;
case 5:
cnt = Count(L);
printf("book has %d\n",cnt);
break;
case 6:
bubbleSort(L);
TraverseList(L);
break;
default:
break;
}
}
}
int Insert(LinkList L, Book e)
{
LNode *p;
p= L;
while(p->next)
{
p=p->next;
}
LNode *s;
s = (LNode *)malloc(sizeof(LNode));
s->elem = e;
s->next = p->next;
p->next= s;
return OK;
}
int TraverseList(LinkList L)
{
LNode *p;
p=L->next;
while(p)
{
printf("ISBN:%s name:%s price:%f\n",p->elem.ISBN,p->elem.name,p->elem.price);
p = p->next;
}
return OK;
}
int Serch(LinkList L,char *bookname)
{
LNode *p;
p = L->next;
while(p&& strcmp(p->elem.name,bookname)!=0)
{
p = p->next;
}
if(p==NULL)
{
printf("Can't find\n");
}
else
{
printf("have this book.\n");
}
return OK;
}
int Delete(LinkList L,char *ISBN)
{
LNode *p;
LNode *prior;
p= L->next;
while(p && strcmp(p->elem.ISBN,ISBN)!=0)
{
prior = p;
p = p->next;
}
if(p==NULL)
{
printf("Can't find\n");
}
else
{
prior->next = p->next;
printf("delete it\n");
}
return OK;
}
int Modify(LinkList L,char *ISBN,char *name,float price)
{
LNode *p;
p = L->next;
while(p&& strcmp(p->elem.ISBN,ISBN)!=0)
{
p = p->next;
}
if(p==NULL)
{
printf("Can't find\n");
}
else
{
strcpy(p->elem.name,name);
p->elem.price = price;
}
return OK;
}
int Count(LinkList L)
{
LNode *p;
int cnt = 0;
p = L->next;
while(p)
{
cnt++;
p = p->next;
}
return cnt;
}
int bubbleSort(LinkList L)
{
if(L->next == NULL || L->next->next == NULL)
return OK; //如果链表是空的或者只有一个元素,直接返回
int flag = 0;
LNode *cur; //游标节点
LNode *pre; //游标节点的前驱节点
LNode *tail = NULL; //尾指针节点
LNode *temp; //临时节点
while(L->next != tail)
{
cur = L->next;
pre = L; //这样确保pre是cur前面的那个节点
while(cur->next != tail )
{
if(strcmp(cur->elem.ISBN,cur->next->elem.ISBN)>0) //这里是根据ISBN的大小进行排序
{
temp = cur->next;
cur->next = temp->next;
temp->next = cur;
pre->next = temp;
pre = temp;
flag = 1;
}
else
{
pre = pre->next;
cur=cur->next;
}
}
if(flag == 0)
return OK;
tail = cur; //使得每次循环结束后,最后一个节点就是最大的元素,尾节点往前挪一位
}
}