news 2026/6/11 2:21:52

用C语言手搓一个图书管理系统:从顺序表到链表的完整实现(附严蔚敏数据结构实验源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用C语言手搓一个图书管理系统:从顺序表到链表的完整实现(附严蔚敏数据结构实验源码)

用C语言手搓一个图书管理系统:从顺序表到链表的完整实现

第一次接触数据结构时,总觉得那些抽象的概念离实际开发很远。直到某天在图书馆借书,看着管理员在电脑上快速检索、入库、出库,突然意识到这不就是线性表的完美应用场景吗?于是决定用C语言实现一个完整的图书管理系统,把课本上的顺序表和链表真正用起来。

这个项目不仅帮我通过了数据结构考试,还成了简历上的亮点。下面我会分享从零开始的完整实现过程,包含可直接运行的源码,特别适合正在学习《数据结构》的C语言初学者。

1. 系统设计与数据结构选型

图书管理系统需要处理的核心操作包括:

  • 图书信息的存储与检索
  • 新书入库与旧书出库
  • 图书信息修改
  • 价格排序与统计
  • 重复书籍检测

数据结构对比分析

特性顺序表链表
内存占用连续空间,可能浪费动态分配,无浪费
插入/删除效率O(n)O(1)
随机访问效率O(1)O(n)
实现难度简单中等
// 图书信息结构体定义 typedef struct { char isbn[20]; // 国际标准书号 char name[50]; // 书名 float price; // 价格 } Book;

2. 顺序表实现方案

顺序表适合数据量固定、查询频繁的场景。我们先实现基础功能:

2.1 顺序表初始化与内存管理

#define MAX_SIZE 1000 typedef struct { Book *elements; // 存储空间基地址 int length; // 当前图书数量 } SeqList; int InitList(SeqList *L) { L->elements = (Book*)malloc(MAX_SIZE * sizeof(Book)); if(!L->elements) exit(OVERFLOW); L->length = 0; return OK; }

内存管理要点

  • 预分配固定大小的连续内存空间
  • 需要检查分配是否成功
  • 记得在程序结束时释放内存

2.2 核心功能实现

图书入库操作示例:

int InsertBook(SeqList *L, int position, Book book) { if (position < 1 || position > L->length + 1) { return ERROR; // 非法位置 } if (L->length >= MAX_SIZE) { return OVERFLOW; // 存储空间已满 } // 移动元素腾出空间 for(int i = L->length; i >= position; i--) { L->elements[i] = L->elements[i-1]; } L->elements[position-1] = book; L->length++; return OK; }

价格调整算法:

void AdjustPrices(SeqList *L) { float total = 0; for(int i = 0; i < L->length; i++) { total += L->elements[i].price; } float avg = total / L->length; for(int i = 0; i < L->length; i++) { if(L->elements[i].price >= avg) { L->elements[i].price *= 1.1; // 高于平均价涨10% } else { L->elements[i].price *= 1.2; // 低于平均价涨20% } } }

3. 链表实现方案

当需要频繁插入删除时,链表是更好的选择。我们采用带头结点的单链表实现:

3.1 链表结构定义

typedef struct LNode { Book data; struct LNode *next; } LNode, *LinkList; int InitList(LinkList *L) { *L = (LinkList)malloc(sizeof(LNode)); if(!*L) exit(OVERFLOW); (*L)->next = NULL; return OK; }

3.2 链表特色操作

链表逆序存储实现:

void ReverseList(LinkList *L) { LNode *prev = NULL; LNode *current = (*L)->next; LNode *next = NULL; while(current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } (*L)->next = prev; }

链表去重算法:

void RemoveDuplicates(LinkList *L) { LNode *current = (*L)->next; while(current != NULL) { LNode *runner = current; while(runner->next != NULL) { if(strcmp(runner->next->data.isbn, current->data.isbn) == 0) { LNode *temp = runner->next; runner->next = runner->next->next; free(temp); } else { runner = runner->next; } } current = current->next; } }

4. 性能优化实战技巧

在实际开发中,我们还需要考虑以下优化点:

4.1 混合存储策略

结合顺序表和链表的优点:

  • 主存储使用顺序表便于快速检索
  • 最近操作记录使用链表实现LRU缓存
typedef struct { SeqList main_storage; // 主存储 LinkList recent_ops; // 最近操作缓存 int cache_size; // 缓存大小 } HybridStorage;

4.2 索引优化

为常用查询字段建立索引:

typedef struct { char isbn[20]; int position; // 在顺序表中的位置 } ISBN_Index; ISBN_Index *CreateISBNIndex(SeqList *L) { ISBN_Index *index = (ISBN_Index*)malloc(L->length * sizeof(ISBN_Index)); for(int i=0; i<L->length; i++) { strcpy(index[i].isbn, L->elements[i].isbn); index[i].position = i; } // 按ISBN排序索引 qsort(index, L->length, sizeof(ISBN_Index), CompareISBN); return index; }

4.3 文件持久化

将数据保存到文件实现持久化:

void SaveToFile(SeqList *L, const char *filename) { FILE *fp = fopen(filename, "wb"); if(fp == NULL) return; fwrite(&(L->length), sizeof(int), 1, fp); fwrite(L->elements, sizeof(Book), L->length, fp); fclose(fp); } int LoadFromFile(SeqList *L, const char *filename) { FILE *fp = fopen(filename, "rb"); if(fp == NULL) return ERROR; fread(&(L->length), sizeof(int), 1, fp); L->elements = (Book*)malloc(L->length * sizeof(Book)); fread(L->elements, sizeof(Book), L->length, fp); fclose(fp); return OK; }

5. 完整系统实现

将各个模块组合成完整系统:

int main() { SeqList bookList; InitList(&bookList); // 加载初始数据 if(LoadFromFile(&bookList, "books.dat") != OK) { printf("初始化图书数据...\n"); // 添加示例图书 Book sampleBooks[5] = { {"9787302257646", "程序设计基础", 25.00}, {"9787302164340", "程序设计基础(第2版)", 20.00}, {"9787302219972", "单片机技术及应用", 32.00}, {"9787302203513", "单片机原理与应用技术", 26.00}, {"7810827430", "工业计算机控制技术", 29.00} }; for(int i=0; i<5; i++) { InsertBook(&bookList, i+1, sampleBooks[i]); } } // 主菜单界面 while(1) { printf("\n图书管理系统\n"); printf("1. 添加新书\n"); printf("2. 删除图书\n"); printf("3. 查询图书\n"); printf("4. 价格调整\n"); printf("5. 保存退出\n"); int choice; scanf("%d", &choice); switch(choice) { case 1: AddBook(&bookList); break; case 2: DeleteBook(&bookList); break; case 3: SearchBook(&bookList); break; case 4: AdjustPrices(&bookList); break; case 5: SaveToFile(&bookList, "books.dat"); free(bookList.elements); return 0; default: printf("无效选择\n"); } } }

实现这个系统的过程中,最深的体会是:数据结构的选择会极大影响系统性能。当图书数量超过5000本时,顺序表的插入操作明显变慢,这时就需要考虑改用链表或其他更高效的数据结构。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 2:21:46

高通ABL源码实战:如何修改代码实现自定义启动模式(如长按音量键进入特殊诊断模式)

高通ABL源码深度定制&#xff1a;实现长按组合键进入诊断模式的完整指南在嵌入式系统开发中&#xff0c;启动流程的定制化往往是产品差异化的关键。当标准Fastboot模式无法满足特殊调试需求时&#xff0c;如何在ABL阶段实现自定义启动路径成为开发者必须掌握的技能。本文将带您…

作者头像 李华
网站建设 2026/6/11 2:20:40

GTAIV.EFLC.FusionFix终极指南:让经典游戏在现代系统重获新生

GTAIV.EFLC.FusionFix终极指南&#xff1a;让经典游戏在现代系统重获新生 【免费下载链接】GTAIV.EFLC.FusionFix This project aims to fix or address some issues in Grand Theft Auto IV: The Complete Edition 项目地址: https://gitcode.com/gh_mirrors/gt/GTAIV.EFLC.…

作者头像 李华
网站建设 2026/6/11 2:15:57

用GPT-4结构化Prompt快速构建Streamlit动态可视化应用

1. 项目概述&#xff1a;用 GPT-4 快速构建可动画的 Streamlit 可视化应用你有没有过这种体验&#xff1a;手头有一份沉甸甸的全球难民流动数据&#xff0c;想快速做出一个能直观展示趋势变化的交互式网页&#xff0c;但一想到要从零写前端、搭后端、配路由、调动画参数&#x…

作者头像 李华
网站建设 2026/6/11 2:15:08

用FPGA+TDC-GPX2测时间间隔,实测误差能到多少?附Vivado工程源码

FPGATDC-GPX2时间间隔测量精度实测与分析 在精密时间测量领域&#xff0c;亚纳秒级精度的实现一直是工程师们追求的目标。本文将带您深入探索基于Xilinx FPGA和TDC-GPX2时间数字转换器搭建的高精度时间间隔测量系统&#xff0c;通过实测数据揭示系统在不同条件下的性能表现&…

作者头像 李华
网站建设 2026/6/11 2:09:22

5套企业级开源框架!Java/Python/AI全栈全覆盖,MIT永久免费商用

摘要&#xff1a;红信鸽技术团队宣布&#xff0c;旗下自主研发的五大企业级开发框架——ThinkPython、ThinkBoot、ThinkBootCloud、ThinkAi、ThinkAi4j——已全部在官网 think.hongxinge.com 免费开源&#xff0c;MIT协议&#xff0c;支持商用。覆盖Python Web、Java单体应用、…

作者头像 李华