赞
踩
本节关键字:Linux、C语言、链表、信息管理系统
相关C库函数:malloc、free、memset、memcpy、sizeof、strcmp、printf
大白话,就是多块地址连续或不连续的内存首尾相连组成的一个集体,可以实现节点的增删改查。链表的本质是一种“数据结构”,实现了数据的链式存储方式。
开辟的空间不连续、有需求再开辟空间,见缝插针式存储。
单向链表:每个节点由数据域和指针域组成,并且每个节点的指针域存储的是下一个节点的地址;
单向循环链表:每个节点由数据域和指针域组成,并且尾节点的指针域存储的是头节点的地址;
双向链表:每个节点由数据域和两个指针域组成,一个指针域存储前一个节点的地址,另一个指针域存储后一个节点的地址;
双向循环链表:每个节点由数据域和两个指针域组成,并且头节点的前一个节点是尾节点,尾节点的后一个节点是头节点,实质上就是两个单向循环链表。
链表的使用很广泛,这里我们就利用本节举例将之前所学的知识点进行复习。题目就是比较火爆的“简易版学生信息管理系统”。
/** * 程序:简易版学生信息管理系统 * 作者:Tianwx_ * 时间:2020.04.11 */ #include <stdio.h> #include <string.h> #include <stdlib.h> // 定义学生信息 typedef struct info_t { char name[64]; // 姓名 char sex[16]; // 性别 int age; // 年龄 char major[128]; // 专业 int score; // 成绩 int no; // 学号 } info_t; // 定义节点 typedef struct node_t { struct node_t *pLast; info_t info; struct node_t *pNext; } node_t; // 定义系统信息 typedef struct sys_info_t { node_t *pHead; // 头节点 node_t *pTail; // 尾节点 int sCount; // 学生数量 } sys_info_t; typedef node_t* pnode_t; typedef node_t* phead_t; enum user_cmd { CMD_EXIT, CMD_ADD, CMD_DELETE, CMD_UPDATE, CMD_FIND, CMD_FILTER, CMD_PRINT, }; pnode_t createLinkNode(); // 创建链表节点 phead_t createLinkHead(); // 创建链表头节点 pnode_t addLinkNode(phead_t head, info_t info); // 增加一个链表节点 pnode_t deleteLinkNode(phead_t head, info_t info); // 删除一个链表节点 pnode_t updateLinkNode(phead_t head, info_t info); // 更新指定学生信息 void findLinkNode(phead_t head, info_t info); // 筛选指定学生信息 void printLinkNode(phead_t head); // 罗列所有学生信息 int compare(info_t *info1, info_t *info2); // 比较学生信息 int update(info_t *info1, info_t *info2); // 更新学生信息 int filter(info_t *info1, info_t *info2); // 过滤学生信息 void print(info_t *info); // 打印学生信息 int menu(); // 打印菜单 void readUserInfo(phead_t head, int cmd); // 读取用户输入 void studentInfoTest(); // 测试接口 sys_info_t g_SystermInformation; int main(int argc, char *argv[]) { studentInfoTest(); return 0; } pnode_t createLinkNode() { pnode_t pnode = (pnode_t)malloc(sizeof(node_t)); if (!pnode) return NULL; memset(pnode, 0, sizeof(node_t)); return pnode; } phead_t createLinkHead() { static phead_t pLinkHead = NULL; if (pLinkHead) return pLinkHead; pLinkHead = (phead_t)malloc(sizeof(node_t)); if (!pLinkHead) return NULL; memset(pLinkHead, 0, sizeof(node_t)); return pLinkHead; } pnode_t addLinkNode(phead_t head, info_t info) { if (!head) return NULL; pnode_t ptail = head; while (ptail->pNext) ptail = ptail->pNext; pnode_t pnode = createLinkNode(); if (!pnode) return NULL; memcpy(&pnode->info, &info, sizeof(info)); ptail->pNext = pnode; pnode->pLast = ptail; g_SystermInformation.sCount += 1; g_SystermInformation.pTail = pnode; printf("\033[32m添加成功!\n\n\n\033[0m"); return pnode; } pnode_t deleteLinkNode(phead_t head, info_t info) { if (!head) return NULL; pnode_t plast = NULL; pnode_t pnext = NULL; pnode_t ptail = head->pNext; while (ptail) { if (compare(&ptail->info, &info) != 0) { ptail = ptail->pNext; continue; } plast = ptail->pLast; pnext = ptail->pNext; plast->pNext = pnext; pnext->pLast = plast; g_SystermInformation.sCount -= 1; if (ptail->pNext == NULL) g_SystermInformation.pTail = ptail->pLast; free(ptail); break; } return pnext; } pnode_t updateLinkNode(phead_t head, info_t info) { if (!head) return NULL; pnode_t ptail = head->pNext; while (ptail) { if (ptail->info.no != info.no) { ptail = ptail->pNext; continue; } if (update(&ptail->info, &info) != 0) ptail = NULL; break; } return ptail; } void findLinkNode(phead_t head, info_t info) { if (!head) return; printf("学号\t姓名\t性别\t年龄\t专业\t成绩\n"); pnode_t ptail = head->pNext; while (ptail) { filter(&ptail->info, &info); ptail = ptail->pNext; } } void printLinkNode(phead_t head) { if (!head) return; printf("@输出学生信息开始(共计学生 %d 名)\n", g_SystermInformation.sCount); printf("学号\t姓名\t性别\t年龄\t专业\t成绩\n"); pnode_t ptail = head->pNext; while (ptail) { print(&ptail->info); ptail = ptail->pNext; } printf("@输出学生信息结束(共计学生 %d 名)\n\n\n", g_SystermInformation.sCount); } /** * @brief compare * @param info1 * @param info2 * @return 相同返回0, 不同返回非零 */ int compare(info_t *info1, info_t *info2) { if (!info1 && !info2) return 0; if (!info1 && info2) return 1; if (info1 && !info2) return 2; if (info1->no != info2->no) return 3; if (strcmp(info1->name, info2->name) != 0) return 4; if (strcmp(info1->sex, info2->sex) != 0) return 5; if (info1->age != info2->age) return 6; if (strcmp(info1->major, info2->major) != 0) return 7; if (info1->score != info2->score) return 8; return 0; } int update(info_t *info1, info_t *info2) { if (!info1) return 1; if (!info2) return 2; if (info1->no != info2->no) return 3; if (strcmp(info1->name, info2->name) != 0) { memset(info1->name, 0, sizeof(info1->name)); strcpy(info1->name, info2->name); } if (strcmp(info1->sex, info2->sex) != 0) { memset(info1->sex, 0, sizeof(info1->sex)); strcpy(info1->sex, info2->sex); } if (info1->age != info2->age) info1->age = info2->age; if (strcmp(info1->major, info2->major) != 0) { memset(info1->major, 0, sizeof(info1->major)); strcpy(info1->major, info2->major); } if (info1->score != info2->score) info1->score = info2->score; return 0; } int filter(info_t *info1, info_t *info2) { char cFlag = 0; if (!info1) return 1; if (!info2) return 2; if (info1->no != 0) if (info1->no != info2->no) return 3; cFlag |= 1; if (strlen(info2->name) > 0) if (strcmp(info1->name, info2->name) != 0) return 4; cFlag |= 1<<1; if (strlen(info2->sex) > 0) if (strcmp(info1->sex, info2->sex) != 0) return 5; cFlag |= 1<<2; if (info1->age != 0) if (info1->age != info2->age) return 6; cFlag |= 1<<3; if (strlen(info2->major) > 0) if (strcmp(info1->major, info2->major) != 0) return 7; cFlag |= 1<<4; if (info1->score != 0) if (info1->score != info2->score) return 8; cFlag |= 1<<5; if (cFlag>>0 & 1) printf("\033[31m%d\t", info1->no); if (cFlag>>1 & 1) printf("%s\t", info1->name); if (cFlag>>2 & 1) printf("%s\t", info1->sex); if (cFlag>>3 & 1) printf("%d\t", info1->age); if (cFlag>>4 & 1) printf("%s\t", info1->major); if (cFlag>>5 & 1) printf("%d\n\033[0m", info1->score); return 0; } void print(info_t *info) { printf("%d\t%s\t%s\t%d\t%s\t%d\n", info->no, info->name, info->sex, info->age, info->major, info->score); } int menu() { int chioce; printf("**************************************\n"); printf("* 1 - 增加学生信息\n"); printf("* 2 - 删除学生信息\n"); printf("* 3 - 更新学生信息\n"); printf("* 4 - 查找学生信息\n"); printf("* 5 - 过滤学生信息\n"); printf("* 6 - 打印所有学生信息\n"); printf("* 0 - 退出\n"); printf("**************************************\n"); printf("请输入您的选择: "); scanf("%d", &chioce); return chioce; } void readUserInfo(phead_t head, int cmd) { info_t info; memset(&info, 0, sizeof(info)); if (cmd == CMD_PRINT) { printLinkNode(head); return; } if (cmd == CMD_ADD) { printf("请输入学号: "); scanf("%d", &info.no); printf("请输入姓名: "); scanf("%s", info.name); printf("请输入性别: "); scanf("%s", info.sex); printf("请输入年龄: "); scanf("%d", &info.age); printf("请输入专业: "); scanf("%s", info.major); printf("请输入成绩: "); scanf("%d", &info.score); } else { printf("请输入学号(跳过请输入 -1): "); scanf("%d", &info.no); printf("请输入姓名(跳过请输入 \\0): "); scanf("%s", info.name); printf("请输入性别(跳过请输入 \\0): "); scanf("%s", info.sex); printf("请输入年龄(跳过请输入 -1): "); scanf("%d", &info.age); printf("请输入专业(跳过请输入 \\0): "); scanf("%s", info.major); printf("请输入成绩(跳过请输入 -1): "); scanf("%d", &info.score); } switch (cmd) { case CMD_EXIT: exit(0); break; case CMD_ADD: addLinkNode(head, info); break; case CMD_DELETE: deleteLinkNode(head, info); break; case CMD_UPDATE: updateLinkNode(head, info); break; case CMD_FIND: findLinkNode(head, info); break; case CMD_FILTER: findLinkNode(head, info); break; case CMD_PRINT: printLinkNode(head); break; default: break; } } void studentInfoTest() { g_SystermInformation.pHead = createLinkHead(); if (g_SystermInformation.pHead == NULL) { printf("程序初始化失败,退出!\n"); exit(0); } while (1) { readUserInfo(g_SystermInformation.pHead, menu()); } } /** 运行结果:步骤较多请自行验证 */
该版本为最基础版本,需要更加完善的版本请点赞关注后私信获取!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。