#include
#include
#include
#include
#define LONGEST_LEN 20 /*使用哈希函数时最多的分类数目*/
#define NUMBER 10 /*原文件中存储的图书信息的数目*/
#define NULL 0
struct book
{
char chiname[20]; /*图书的中文名*/
char isbn[15]; /*图书的ISBN码*/
char autname[20]; /*作者的名字*/
char publishinghouse[50]; /*出版社名*/
struct book *next;
};
typedef struct book BOOK;
BOOK *symtab[LONGEST_LEN]; /*创建链表数组*/
char Menu();
void Print(BOOK *sym[]);
void Appendnode(BOOK *sym[]);
void Deletenode(BOOK *sym[],char Isbn[]);
void Modifynode(BOOK *sym[],char Isbn[]);
void lookup(BOOK *sym[],char Isbn[]);
unsigned int hash(char *str);
void SaveDocument(BOOK *sym[]);
void main()
{
char c,isbn_num[15];
int i;
unsigned int h;
BOOK *p0[NUMBER],*p1;
for(i=0;i
{
p0[i]=(BOOK *)malloc(sizeof(BOOK)); /*为存储图书信息开辟空间*/
p0[i]->next=NULL; /*将每一个节点都指向空*/
}
for(i=0;i
{
symtab[i]=NULL; /*将链表数组初始化为空*/
}
FILE *fp;
fp=fopen("book1.txt","r");
printf("The current document!\n");
for(i=0;i
{
fscanf(fp,"%s %s %s %s\n",p0[i]->chiname,p0[i]->isbn,p0[i]->autname,p0[i]->publishinghouse); /*将文件中的内容读入散列表中*/
h=hash(p0[i]->isbn);
if(symtab[h]==NULL)
symtab[h]=p0[i];
else
{
p1=symtab[h];
while(p1->next!=NULL)
p1=p1->next;
p1->next=p0[i];
}
/*采用表尾插入的方式向散列表中增加新的结点*/
}
fclose(fp);
Print(symtab);
while(1)
{
c=Menu();
switch(c)
{
case'1':Appendnode(symtab);break;
case'2':
{
printf("Please input the ISBN:\n"); /*通过ISBN查找需要删除的图书信息的节点*/
scanf("%s",isbn_num);
Deletenode(symtab,isbn_num);
break;
}
case'3':
{
printf("Please input the ISBN:\n"); /*通过ISBN查找需要修改的图书信息的节点*/
scanf("%s",isbn_num);
Modifynode(symtab,isbn_num);
break;
}
case'4':
{
printf("Please input the ISBN:\n"); /*通过ISBN查找需要查找的图书信息的节点*/
scanf("%s",isbn_num);
lookup(symtab,isbn_num);
break;
}
case'5':Print(symtab);break;
case'6':SaveDocument(symtab);break;
default:exit(0);
}
}
}
/*函数功能:显示菜单并获得用户键盘输入的选项
函数参数:无
函数返回值:用户输入的选项*/
char Menu()
{
char ch;
printf("\n The system of books!\n");
printf("1.Appendnode\n");
printf("2.Deletenode\n");
printf("3.Modifynode\n");
printf("4.Searchnode\n");
printf("5.Printnode\n");
printf("6.Savenode\n");
printf("Please input your option:");
scanf("%c",&ch);
return ch;
}
/*函数功能:打印散列表中存储的信息
函数参数:链表数组的首地址
函数的返回值:无*/
void Print(BOOK *sym[])
{
char c1[10]="book_name",c2[5]="ISBN",c3[12]="autor_name",c4[20]="publishing_house",c5[15]="hash_number";
int i=0;
BOOK *p[LONGEST_LEN],*p0;
printf("%-15s%-18s%-14s%-15s%-15s\n",c5,c1,c2,c3,c4);
while(i
{
p[i]=symtab[i];
p0=p[i];
while(p0!=NULL)
{
printf("%5d",i);
printf("%16s",p0->chiname);
printf("%17s",p0->isbn);
printf("%10s",p0->autname);
printf("%15s\n",p0->publishinghouse);
p0=p0->next;
}
i++;
}
}
/*函数功能:向散列表中添加图书信息
函数参数:链表数组的首地址
函数返回值:无*/
void Appendnode(BOOK *sym[])
{
unsigned int h;
BOOK *p,*p1;
printf("Please input the data you want to append!\n");
p=(BOOK *)malloc(sizeof(BOOK));
printf("Please input the isbn number:");
scanf("%s",p->isbn);
h=hash(p->isbn);
if(sym[h]==NULL)
sym[h]=p;
else
{
p1=sym[h];
while(p1->next!=NULL)
p1=p1->next;
p=p1->next;
}
printf("Please input the chinese name:");
scanf("%s",p->chiname);
printf("Please input the author name:");
scanf("%s",p->autname);
printf("Please input the publishinghouse name:");
scanf("%s",p->publishinghouse);
printf("\n");
Print(sym);
}
/*函数功能:删除指定ISBN码的结点
函数参数:链表数组的首地址,需要删除的ISBN码序列
函数返回值:无*/
void Deletenode(BOOK *sym[],char Isbn[])
{
unsigned int h;
BOOK *p,*p0,*p1;
h=hash(Isbn);
p=sym[h];
while(p!=NULL)
{
if(strcmp(p->isbn,Isbn)==0)
{
p0=p;
break;
}
else p=p->next;
}
if(p==NULL)
printf("The ISBN number has not been found!\n");
else
{
p1=sym[h];
if(p1->next!=p0) p1=p1->next;
p1->next=p0->next;
free(p0);
Print(sym);
}
}
/*函数功能:通过ISBN查找需要修改的图书信息的节点,选择需要修改的选项
函数参数:链表数组的首地址,需要修改的ISBN码序列
函数返回值:无*/
void Modifynode(BOOK *sym[],char Isbn[])
{
unsigned int h1;
BOOK *p,*p0;
h1=hash(Isbn);
p=sym[h1];
while(p!=NULL)
{
if(strcmp(p->isbn,Isbn)==0)
{
p0=p;
break;
}
else p=p->next;
}
if(p==NULL)
printf("The ISBN number has not been found!\n");
else
{
scanf("%s",p0->chiname);
scanf("%s",p0->autname);
scanf("%s",p0->publishinghouse);
printf("\n");
Print(sym);
}
}
/*函数功能:在散列表中按照ISBN码来查找相应的图书信息如果没有找到,则将该信息添加进散列表
函数参数:链表数组的首地址,需要查找的ISBN码序列
函数返回值:无*/
void lookup(BOOK *sym[],char Isbn[])
{
unsigned int h;
BOOK *p,*p0;
char c1[10]="book_name",c2[5]="ISBN",c3[12]="autor_name",c4[20]="publishing_house";
h=hash(Isbn);
p=sym[h];
while(p!=NULL)
{
if(strcmp(p->isbn,Isbn)==0)
{
p0=p;
break;
}
else p=p->next;
}
if(p!=NULL)
{
printf("The node has been found!\n");
printf("%-5s%-10s%-5s%-5s",c1,c2,c3,c4);
printf("%s",p->chiname);
printf("%s",p->isbn);
printf("%s",p->autname);
printf("%s\n",p->publishinghouse);
}
else Appendnode(sym);
}
/*函数功能:利用除留余数法算出哈希表的值
函数参数:指向字符型的指针
函数返回值:无符号整形*/
unsigned int hash(char *str)
{
enum{SIZE=31};
unsigned int i,h;
h=0;
for(i=0;i
h=SIZE*h+str[i];
return h%LONGEST_LEN;
}
/*函数功能:将修改后的图书信息存放到文件中
函数参数:链表数组的首地址
函数的返回值:无*/
void SaveDocument(BOOK *sym[])
{
int i=0;
BOOK *p;
FILE *fp;
fp=fopen("book2.txt","w");
while(i
{
if(sym[i]!=NULL)
{
p=sym[i];
while(p!=NULL)
{
fprintf(fp,"%s %s %s %s\n",p->chiname,p->isbn,p->autname,p->publishinghouse);
p=p->next;
}
i++;
}
else i++;
}
fclose(fp);
}