一、实验题目
图书信息管理系统
出版社有一些图书数据,为简单起见,在此假设每种图书只包括三部分信息:ISBN (书号)、书名和价格,文件中的部分数据如图2.1所示。现要求实现一个图书信息管理系统,包括以下6个具体功能。
(1)查找:根据指定的ISBN或书名查找相应图书的有关信息,并返回该图书在表中的位置序号。
(2)插入:插入一种新的图书信息。
(3)删除:删除一种图书信息。
(4)修改:根据指定的ISBN,修改该图书的价格。
(5)排序:将图书按照价格由低到高进行排序。
(6)计数:统计图书表中的图书数量。
二、工具环境
Window10操作系统,Microsoft Visual C++2010学习版 集成开发环境,C语言
三、实验问题
在使用结构体指针的时候,必须先用malloc分配空间,再进行赋值,并且每次没有明确指向的指针都要赋值为NULL
四、实验代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 100
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct {
int num;//序号
char ISBN[20];
char name[N+1];
int price;
}Book;
typedef struct LNode{
Book * book;//结点的数据域
struct LNode *next;//结点的指针域
}LNode,*LinkList;//LinkList 为指向结构体 LNode 的指针类型
Status InitList(LinkList *L); //初始化指针L
Status CreateList(LinkList L,LinkList q,Book *book);//初始化指针L的next指针p
LNode *LocateELem(LinkList L, char ISBN[],char name[]);//查找
Status Listinsert(LinkList L,LinkList p,LinkList q);//添加
Status ListDelete(LinkList L,LinkList p);//删除
Status ListAlter(LinkList L,LinkList p);//修改
Status ListOrder(LinkList L);//排序
Status ListDefaultOrder(LinkList L);//默认排序
int GetNumber(LinkList L);//统计个数
Status showbook(LinkList L);
int main()//---------------------------------主函数---------------------------------
{
LinkList L=NULL,p=NULL,temp=NULL;
Book book1={1,"9787302257646","程序设计基础",25};
Book book2={2,"9787302219972","单片机技术及应用",32};
Book book3={3,"9787302203513","编译原理",46};
Book book4={4,"9787811234923","汇编语言程序设计教程",21};
Book book5={5,"9787512100831","计算机操作系统",17};
Book book6={6,"9787302265436","计算机导论实验指导",18};
Book book7={7,"9787302180630","实用数据结构",29};
Book book8={8,"9787302225065","数据结构(C语言版)",38};
Book book9={9,"9787302171676","C#面向对象程序设计",39};
Book book10={10,"9787302250692","C语言程序设计",42};
Book book11={11,"9787302150664","数据库原理",35};
Book book12={12,"9787302260806","Java编程与实践",56};
Book book13={13,"9787302252887","Java程序设计与应用教程",39};
Book book14={14,"9787302198505","嵌入式操作系统及编程",25};
Book book15={15,"9787302169666","软件测试",24};
Book book16={16,"9787811231557","Eclipse基础与应用",35};
char ISBN[20],name[N+1];
int length;
system("color f1");
InitList(&L);InitList(&p);InitList(&temp);//初始化头指针,L做头指针始终指向头节点
//现在L和p的数据域空,指针域指向空
CreateList(p,p->next,&book1);
p=p->next;//p的指针域指向第一条图书信息
L->next=p;//L的下一个指向首元结点
temp=p;//记录首元结点位置
CreateList(p,p->next,&book2);
p=p->next;
CreateList(p,p->next,&book3);
p=p->next;
CreateList(p,p->next,&book4);
p=p->next;
CreateList(p,p->next,&book5);
p=p->next;
CreateList(p,p->next,&book6);
p=p->next;
CreateList(p,p->next,&book7);
p=p->next;
CreateList(p,p->next,&book8);
p=p->next;
CreateList(p,p->next,&book9);
p=p->next;
CreateList(p,p->next,&book10);
p=p->next;
CreateList(p,p->next,&book11);
p=p->next;
CreateList(p,p->next,&book12);
p=p->next;
CreateList(p,p->next,&book13);
p=p->next;
CreateList(p,p->next,&book14);
p=p->next;
CreateList(p,p->next,&book15);
p=p->next;
CreateList(p,p->next,&book16);
p=p->next;//现在p在16
printf("\t------------------------------------\n");
printf("\t——欢迎使用图书信息管理系统——\n");
printf("\t0. 退出学图书信息管理系统\n");
printf("\t1. 查找图书\n");
printf("\t2. 添加图书\n");
printf("\t3. 删除图书\n");
printf("\t4. 修改图书\n");
printf("\t5. 按图书价格排序\n");
printf("\t6. 统计图书数量\n");
showbook(L);
while(1)
{
int choose;
printf("\n\t请输入你要选择的功能前的序号:");
scanf("%d",&choose);
if(choose==0){
printf("\n\t退出成功,谢谢使用图书信息管理系统!");
break;
}
switch(choose)
{
case 1://"1. 查找图书\n");
LocateELem(L,ISBN,name);
break;
case 2://"2. 添加图书\n");
Listinsert(L,p,p->next);
break;
case 3://3. 删除图书\n");
ListDelete(L,p);
break;
case 4://4. 修改图书\n");
ListAlter(L,p);
break;
case 5://5. 按图书价格排序\n");
ListOrder(L);
ListDefaultOrder(L);//默认按序号排序
break;
case 6://6. 统计图书数量\n");
length=GetNumber(L);
printf("\n\t共有%d本图书\n",length);
break;
}
}
return 0;
}//---------------------------------主函数---------------------------------
Status InitList(LinkList *L)
{
*L=(LinkList)malloc(1*sizeof(LNode));
(*L)->next=NULL;//★
return OK;
}
Status CreateList(LinkList p,LinkList q,Book *book)
{ //q=p->next;
q=(LinkList)malloc(1*sizeof(LNode));//p->next初始化★
q->book=book;//p->next数据域赋值
q->next=NULL;//p->next指针域为空,等待后续建立连接★
p->next=q;p->next指针域与初始化后的指针建立连接
return OK;
}
LNode *LocateELem(LinkList L, char ISBN[],char name[])
{
int i=0,choose=0,flag=0;//flag=1说明选择方式正确;flag=-1说明查找到图书
LinkList p=L->next;//初始化,p指向首元结点
printf("\n\t请选择查找图书的方式: 1.按ISBN查找,2.按书名查找:\n");
printf("\t请输入:");
scanf("%d",&choose);
while(flag!=1){
switch(choose){
case 1:
printf("\t请输入要查找图书的ISBN:");
scanf("%s",ISBN);
while(p!=NULL)
{
if(strcmp(ISBN,p->book->ISBN)==0){
printf("\n\t查找到ISBN为%s的图书序号为%d\n",ISBN,p->book->num);
flag=-1;
break;
}
p=p->next;
}
if(flag!=-1)
printf("\n\t不存在该图书\n");
flag=1;
break;
case 2:
printf("\t请输入要查找图书的名字:");
scanf("%s",name);
while(p!=NULL)
{
if(strcmp(name,p->book->name)==0){
printf("\n\t查找到名字为%s的图书序号为%d\n",name,p->book->num);
flag=-1;
break;
}
p=p->next;
}
if(flag!=-1)
printf("\n\t不存在该图书\n");
flag=1;
break;
default:
printf("\n\t请重新输入:");
scanf("%d",&choose);
break;
}
}
return p;
}
Status Listinsert(LinkList L,LinkList p,LinkList q)
{
char ISBN[20],name[N+1];
int price;
Book *book=(Book *)malloc(1*sizeof(Book));
p=L;
q=(LinkList)malloc(1*sizeof(LNode));//插入结点
while(p->next!=NULL)
{
p=p->next;
}
printf("\t请输入要添加的图书信息:\n");
printf("\t请输入图书的ISBN:");scanf("%s",book->ISBN);
printf("\t请输入图书的名字:");scanf("%s",book->name);
printf("\t请输入图书的价格:");scanf("%d",&(book->price));
book->num=(p->book->num) +1;
q->book=book;
q->next=NULL;
p->next=q;
printf("\n\t添加成功\n");
return OK;
}
Status ListDelete(LinkList L,LinkList p)
{
int i,j,num,flag=0;
char ISBN[20];
LinkList q=(LinkList)malloc(1*sizeof(LNode));//保存被释放的结点
LinkList temp=(LinkList)malloc(1*sizeof(LNode));
p=L;
printf("\t请输入你要删除的图书的ISBN:");scanf("%s",ISBN);
while(p->next!=NULL)
{
if(strcmp(ISBN,p->next->book->ISBN)==0){
q=p->next;
temp=p->next;
flag=1;
break;
}
p=p->next;
}
if(flag!=1)
{
printf("\n\t找不到此图书\n");
return ERROR;
}else{
if(temp->next!=NULL){
temp->next->book->num=temp->book->num;
temp=temp->next;}
while(temp->next!=NULL){
temp->next->book->num=(temp->book->num)+1;
temp=temp->next;
}
if(q->next!=NULL){
p->next=q->next;
free(q);
}else{
p->next=NULL;
}
printf("\n\t删除成功\n");
return OK;
}
}
Status ListAlter(LinkList L,LinkList p)
{
int i,choose,price,flag=0;
char ISBN[20],name[N+1];
p=L;
printf("\t请输入你要修改的图书的ISBN:");scanf("%s",ISBN);
while(p->next!=NULL)
{
if(strcmp(ISBN,p->next->book->ISBN)==0){
p=p->next;
flag=1;
break;
}
p=p->next;
}
if(flag==1){
while(1)
{
printf("\t0. 退出修改\n");
printf("\t1. 修改ISBN\n");
printf("\t2. 修改名字\n");
printf("\t3. 修改价格\n");
printf("\n\t请输入你要选择的功能前的序号:");
scanf("%d",&choose);
if(choose==0) break;
switch(choose)
{
case 1://"1. 修改ISBN");
printf("\t请输入图书的ISBN:");scanf("%s",ISBN);
strcpy(p->book->ISBN,ISBN);
break;
case 2://"2. 修改名字");
printf("\t请输入图书的名字:");scanf("%s",name);
strcpy(p->book->name,name);
break;
case 3://3. 修改价格");
printf("\t请输入图书的价格:");scanf("%d",&price);
p->book->price=price;
break;
}
}//while
printf("\n\t修改成功\n");
}else{
printf("\t找不到此图书\n");
return ERROR;
}
return OK;
}
Status ListOrder(LinkList L)
{
LinkList E=(LinkList)malloc(1*sizeof(LNode));
LinkList p=(LinkList)malloc(1*sizeof(LNode));
LinkList q=(LinkList)malloc(1*sizeof(LNode));
Book *temp=(Book *)malloc(1*sizeof(Book));
E=L;
L=L->next;
while(L->next!=NULL)
{
p=L;
q=L->next;
while(q!=NULL)
{
if(p->book->price > q->book->price)
{
temp=p->book;
p->book=q->book;
q->book=temp;
}
q=q->next;
}
L=L->next;
}
L=E->next;
printf("\n\t序号\t\tISBN\t\t名字\t\t\t价格\n");
while(L!=NULL)
{
printf("\t %d \t %-13s \t %-22s \t %d\n",L->book->num,L->book->ISBN,L->book->name,L->book->price);
L=L->next;
}
L=E;
return OK;
}
Status ListDefaultOrder(LinkList L)
{
LinkList E=(LinkList)malloc(1*sizeof(LNode));
LinkList p=(LinkList)malloc(1*sizeof(LNode));
LinkList q=(LinkList)malloc(1*sizeof(LNode));
Book *temp=(Book *)malloc(1*sizeof(Book));
E=L;
L=L->next;
while(L->next!=NULL)
{
p=L;
q=L->next;
while(q!=NULL)
{
if(p->book->num > q->book->num)
{
temp=p->book;
p->book=q->book;
q->book=temp;
}
q=q->next;
}
L=L->next;
}
L=E;
return OK;
}
int GetNumber(LinkList L)
{
LinkList p=(LinkList)malloc(1*sizeof(LNode));
p=L;
while(p->next!=NULL)
{
p=p->next;
}
return p->book->num;
}
Status showbook(LinkList L)
{
LinkList p=(LinkList)malloc(1*sizeof(LNode));
p=L->next;
printf("\t---------------------------------------------------------------\n");
printf("\t序号\t\tISBN\t\t名字\t\t\t价格\n");
while(p!=NULL)
{
printf("\t %d \t %-13s \t %-22s \t %d\n",p->book->num,p->book->ISBN,p->book->name,p->book->price);
p=p->next;
}
free(p);
printf("\t---------------------------------------------------------------\n");
return OK;
}
五、实验总结
空间:
顺序表:空间大小需要提前分配,会有闲置和溢出
链表:大小可以任意改变,不会出现闲置和溢出
时间:
顺序表:增删比较麻烦,平均需要移动一半的元素
链表:增删比较容易只需要改结点指向
感觉写图书信息管理系统还是顺序表好用,但是不易扩展,链表每次不管增删改查,使用完指针位置都会变,就感觉好麻烦