用c语言制作一个链式表的图书管理系统,要求如下: (1)根据指定图书个数,逐个输入图书信息(包括序号 书名 ISBN 作者 出版社 价格); (2)逐个显示所有图书的相关信息; (3)给定一个图书信息,插入到表中指定的位置; (4)删除指定位置的图书信息; (5)统计表中图书个数; (6)利用快速排序按照序号进行排序; (7)分别利用直接插入排序和折半插入排序按照ISBN进行排序; (8)根据ISBN进行折半查找,成功返回此图书的书名和作者。
时间: 2024-01-21 21:02:00 浏览: 85
好的,这是一个比较复杂的问题,需要用到链表、排序和查找等知识。我会尽可能详细地回答你的问题,但是由于篇幅限制,可能无法提供完整的代码。不过,我会给出关键的代码片段和思路,希望能帮助到你。
首先,我们需要定义一个图书的结构体。结构体中包含了图书的各种信息,比如序号、书名、ISBN、作者、出版社和价格等。我们可以定义如下的结构体:
```c
typedef struct book {
int id; // 序号
char name[50]; // 书名
char isbn[20]; // ISBN
char author[20];// 作者
char publisher[30]; // 出版社
float price; // 价格
struct book *next; // 指向下一个结点的指针
} Book;
```
这个结构体中包含了一个指向下一个结点的指针,这是链表的核心。
接下来,我们需要定义一个链表,包含了各种操作,比如插入、删除、遍历和排序等。链表的头结点不存储具体的图书信息,只是一个指向第一个结点的指针。我们可以定义如下的链表结构体:
```c
typedef struct bookList {
int length; // 链表中结点的个数
Book *head; // 头结点指针
} BookList;
```
有了链表结构体之后,我们可以实现各种操作了。下面是一些关键的代码片段:
1. 插入操作
插入操作可以分为两种情况。第一种是在链表的末尾插入结点,第二种是在链表的中间插入结点。我们可以根据用户输入的插入位置来判断具体的插入操作。
```c
// 在链表的末尾插入结点
void append(BookList *list, Book book) {
Book *newNode = (Book*)malloc(sizeof(Book));
*newNode = book;
newNode->next = NULL;
if (list->head == NULL) {
list->head = newNode;
} else {
Book *p = list->head;
while (p->next != NULL) {
p = p->next;
}
p->next = newNode;
}
list->length++;
}
// 在链表的指定位置插入结点
void insert(BookList *list, Book book, int pos) {
if (pos < 0 || pos > list->length) {
printf("插入位置无效!\n");
return;
}
Book *newNode = (Book*)malloc(sizeof(Book));
*newNode = book;
newNode->next = NULL;
if (pos == 0) {
newNode->next = list->head;
list->head = newNode;
} else {
Book *p = list->head;
for (int i = 0; i < pos-1; i++) {
p = p->next;
}
newNode->next = p->next;
p->next = newNode;
}
list->length++;
}
```
2. 删除操作
删除操作也可以分为两种情况。第一种是删除链表的第一个结点,第二种是删除链表中间的结点。我们可以根据用户输入的删除位置来判断具体的删除操作。
```c
// 删除链表中指定位置的结点
void delete(BookList *list, int pos) {
if (pos < 0 || pos >= list->length) {
printf("删除位置无效!\n");
return;
}
if (pos == 0) {
Book *p = list->head;
list->head = p->next;
free(p);
} else {
Book *p = list->head;
for (int i = 0; i < pos-1; i++) {
p = p->next;
}
Book *q = p->next;
p->next = q->next;
free(q);
}
list->length--;
}
```
3. 遍历操作
遍历操作可以用来输出链表中所有结点的信息。
```c
// 遍历链表中所有结点
void traverse(BookList *list) {
Book *p = list->head;
while (p != NULL) {
printf("%d\t%s\t%s\t%s\t%s\t%.2f\n", p->id, p->name, p->isbn, p->author, p->publisher, p->price);
p = p->next;
}
}
```
4. 排序操作
排序操作可以用来按照序号或ISBN对链表中的结点进行排序。这里我们使用快速排序和折半插入排序两种算法。
```c
// 快速排序
void quickSort(BookList *list, int left, int right) {
if (left >= right) {
return;
}
Book *pivot = list->head;
int i = left, j = right;
while (i < j) {
while (i < j && pivot->id <= list->head[j].id) {
j--;
}
if (i < j) {
list->head[i++] = list->head[j];
}
while (i < j && pivot->id >= list->head[i].id) {
i++;
}
if (i < j) {
list->head[j--] = list->head[i];
}
}
list->head[i] = *pivot;
quickSort(list, left, i-1);
quickSort(list, i+1, right);
}
// 折半插入排序
void binaryInsertionSort(BookList *list) {
for (int i = 1; i < list->length; i++) {
Book tmp = list->head[i];
int left = 0, right = i-1, mid;
while (left <= right) {
mid = (left + right) / 2;
if (strcmp(tmp.isbn, list->head[mid].isbn) < 0) {
right = mid - 1;
} else {
left = mid + 1;
}
}
for (int j = i-1; j >= left; j--) {
list->head[j+1] = list->head[j];
}
list->head[left] = tmp;
}
}
```
5. 查找操作
查找操作可以根据ISBN来查找图书的信息。
```c
// 折半查找
int binarySearch(BookList *list, char *isbn) {
int left = 0, right = list->length-1, mid;
while (left <= right) {
mid = (left + right) / 2;
if (strcmp(isbn, list->head[mid].isbn) == 0) {
return mid;
} else if (strcmp(isbn, list->head[mid].isbn) < 0) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
```
最后,我们可以在主函数中调用各种操作,来实现一个完整的图书管理系统。
```c
int main() {
BookList list = {0, NULL}; // 初始化链表
int n;
printf("请输入图书的个数:");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
Book book;
printf("请输入第%d本图书的信息:\n", i+1);
printf("序号:");
scanf("%d", &book.id);
printf("书名:");
scanf("%s", book.name);
printf("ISBN:");
scanf("%s", book.isbn);
printf("作者:");
scanf("%s", book.author);
printf("出版社:");
scanf("%s", book.publisher);
printf("价格:");
scanf("%f", &book.price);
append(&list, book); // 将新结点插入链表末尾
}
traverse(&list); // 遍历链表,输出所有结点的信息
// 在指定位置插入新结点
Book newBook = {99, "新书", "1234567890", "作者", "出版社", 20.5};
insert(&list, newBook, 2);
traverse(&list);
// 删除指定位置的结点
delete(&list, 2);
traverse(&list);
// 统计链表中结点的个数
printf("链表中结点的个数:%d\n", list.length);
// 快速排序
quickSort(&list, 0, list.length-1);
traverse(&list);
// 折半插入排序
binaryInsertionSort(&list);
traverse(&list);
// 折半查找
char isbn[20];
printf("请输入要查找的图书的ISBN:");
scanf("%s", isbn);
int pos = binarySearch(&list, isbn);
if (pos >= 0) {
printf("书名:%s,作者:%s\n", list.head[pos].name, list.head[pos].author);
} else {
printf("未找到该图书!\n");
}
return 0;
}
```
这就是一个简单的链式表的图书管理系统的实现。希望对你有所帮助!
阅读全文