数据结构之链表的使用【C语言】
来源:互联网 发布:支持承载网络否 编辑:程序博客网 时间:2024/05/01 12:45
链表在几种数据结构中算是比较简单的,操作也比较简单。链表分为单向、双向、循环链表,其中单向链表是所有链表的基础。结合一个简单的例子,用C语 言实践单向链表的创建、修改、删除操作。在实践的过程中,学习了C语言关于scanf的使用技巧:在scanf使用多次时,需要使用 fflush(stdin)来清空缓冲区,最好每次使用后,就刷新一次,以免出现不确定的输入的问题。
学生信息:姓名、年龄。
操作:1、增加;2、修改;3、删除;4、查询;5、退出。其中查询使用strstr()函数,实现部分匹配查找。顺序查询算法复杂度为O(n)。
缺点:只有顺序添加节点功能,没有随机添加节点功能。
代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define NAMEMAX 40#define SUCCESS 1#define FAIL 0struct student{ char studentName[NAMEMAX]; unsigned int studentAge; struct student* next;};typedef struct student node;typedef struct student* pNode;static int studentNumber;/********* 函数声明 开始 *********/pNode add_student(pNode head);pNode find_lastNode(pNode head);void modify_student(pNode head);pNode delete_student(pNode head);int search_student(pNode head);void quit_student(pNode head);/********* 函数声明 结束 *********//*** * 查找最后一个节点 */pNode find_lastNode(pNode head){ pNode tempPNode; tempPNode = head; while(tempPNode->next != NULL) { tempPNode = tempPNode->next; } return tempPNode;}/*** * 显示学生个人信息 */void show_student_information(pNode node){ printf("姓名:%s\n",node->studentName); printf("年龄:%u\n",node->studentAge);}/** * 增加学生信息 * 创建单向链表 * head:链表头指针 */pNode add_student(pNode head){ char tempName[NAMEMAX];//学生姓名临时变量 unsigned int tempAge;//学生年龄临时变量 pNode tempPNode; pNode tempPPreNode; char isAdd; printf("\n************************\n"); printf(" 增加学生信息\n"); printf("************************\n"); printf("请输入学生姓名: "); scanf("%s",tempName);//输入姓名 printf("请输入学生年龄: "); while((scanf("%u",&tempAge) !=1) || tempAge <=0)//输入年龄 { printf("请输入正确的年龄(大于0的整数): "); } printf("************************\n"); printf("学生信息\n"); printf("姓名:%s\n", tempName); printf("年龄:%u\n", tempAge); printf("是否增加(Y/N): "); fflush(stdin);//刷新缓冲区 while((scanf("%c",&isAdd) != 1) || (isAdd != 'Y' && isAdd != 'y' && isAdd != 'N' && isAdd != 'n'))//是否增加 { printf("请输入Y或者y或者N或者n!\n"); printf("是否增加(Y/N): "); //刷新缓冲区 fflush(stdin); } if(isAdd == 'Y' || isAdd == 'y') { if(head == NULL)//无节点 { head = (pNode)malloc(sizeof(node)); strcpy(head->studentName, tempName); head->studentAge = tempAge; head->next = NULL; } else//有节点 { tempPNode = (pNode)malloc(sizeof(node)); strcpy(tempPNode->studentName, tempName); tempPNode->studentAge = tempAge; tempPNode->next = NULL; tempPPreNode = find_lastNode(head); tempPPreNode->next = tempPNode; } studentNumber ++; printf("增加学生信息成功,"); } else { printf("增加学生信息失败,"); } printf("返回主菜单\n\n"); return head;}/** * 修改学生信息 * 顺序查找链表 */void modify_student(pNode head){ unsigned int index = 0;//选中学生的序号 unsigned int tmpIndex = 0;//临时变量 pNode tmpNode;//节点临时变量 char tmpName[NAMEMAX]; unsigned int tmpAge = 0; char isAdd; if(search_student(head)) { printf("请选择序号:"); while((scanf("%u",&index) != 1) || index == 0) { printf("请输入大于0的整数!\n"); printf("请选择序号:"); fflush(stdin); } tmpNode = head; while(tmpNode) { if(strstr(tmpNode->studentName,tmpName) != NULL)/*查找成功*/ { tmpIndex++; if(tmpIndex == index)//找到 { break; } else//未找到 { tmpNode = tmpNode->next; } } } if(tmpIndex != 0 && tmpIndex == index)//找到 { printf("选中的学生信息:\n"); show_student_information(tmpNode); printf("新信息:\n"); printf("姓名:"); scanf("%s",tmpName); printf("年龄:"); while((scanf("%u",&tmpAge) != 1) || tmpAge == 0) { printf("请输入大于0的整数!\n"); printf("年龄:"); fflush(stdin); } printf("是否修改(Y/N): "); fflush(stdin);//刷新缓冲区 while((scanf("%c",&isAdd) != 1) || (isAdd != 'Y' && isAdd != 'y' && isAdd != 'N' && isAdd != 'n'))//是否增加 { printf("请输入Y或者y或者N或者n!\n"); printf("是否修改(Y/N): "); //刷新缓冲区 fflush(stdin); } if(isAdd == 'Y' || isAdd == 'y')//修改 { strcpy(tmpNode->studentName, tmpName); tmpNode->studentAge = tmpAge; printf("已修改!返回主菜单。\n"); } else//不修改 { printf("未修改!返回主菜单。\n"); } } else//未找到 { printf("未修改!返回主菜单。\n"); return; } }}/*** * 按照姓名模糊查找,并删除相关学生信息 * 删除链表节点 */pNode delete_student(pNode head){ unsigned int index = 0;//选中学生的序号 unsigned int tmpIndex = 0;//临时变量 pNode tmpNode = NULL;//节点临时变量 pNode tmpPreNode = NULL;//要删除的节点的前一个节点临时变量 char tmpName[NAMEMAX]; char isDel; if(search_student(head)) { printf("请选择序号:"); while((scanf("%u",&index) != 1) || index == 0) { printf("请输入大于0的整数!\n"); printf("请选择序号:"); fflush(stdin); } tmpNode = head; while(tmpNode) { if(strstr(tmpNode->studentName,tmpName) != NULL)/*查找成功*/ { tmpIndex++; if(tmpIndex == index)//找到 { break; } else//未找到 { tmpPreNode = tmpNode; tmpNode = tmpNode->next; } } } if(tmpIndex !=0 && tmpIndex == index)//找到 { printf("是否删除(Y/N): "); fflush(stdin);//刷新缓冲区 while((scanf("%c",&isDel) != 1) || (isDel != 'Y' && isDel != 'y' && isDel != 'N' && isDel != 'n'))//是否增加 { printf("请输入Y或者y或者N或者n!\n"); printf("是否删除(Y/N): "); //刷新缓冲区 fflush(stdin); } if(isDel == 'Y' || isDel == 'y')//删除 { if(tmpNode == head)//如果删除的节点为头结点 { head = head->next; } else if(tmpNode->next != NULL)//删除的节点在中间 { tmpPreNode->next = tmpNode->next; tmpNode->next = NULL; } else if(tmpNode->next == NULL)//删除的节点在末尾 { tmpPreNode->next = NULL; } free(tmpNode); tmpNode == NULL; printf("删除成功!返回主菜单。\n"); studentNumber --; } else//不删除 { printf("未删除!返回主菜单。\n"); } } else//未找到 { printf("未找到!返回主菜单。\n"); } } return head;}/*** * 按照姓名模糊查找 * 顺序查找链表 */int search_student(pNode head){ //测试使用 pNode tmpNode; int tmpIndex = 0; char tmpName[NAMEMAX];//学生姓名临时变量 if(head == NULL) { printf("没有学生信息,请添加!返回主菜单。\n"); return FAIL; } printf("\n************************\n"); printf("输入学生姓名【模糊查找】:\n"); fflush(stdin); scanf("%s",tmpName); tmpNode = head; while(tmpNode) { if(strstr(tmpNode->studentName,tmpName) != NULL)/*查找成功*/ { tmpIndex++; printf("%d:\n",tmpIndex); show_student_information(tmpNode); } tmpNode = tmpNode->next; } if(tmpIndex == 0) { printf("没有查找到名字中包含%s的学生!\n",tmpName); printf("\n************************\n"); return FAIL; } printf("\n************************\n"); return SUCCESS;}/** * 退出系统,删除所有学生信息 * 删除链表 */void quit_student(pNode head){ pNode tmpNode1 = NULL; pNode tmpNode2 = NULL; if(head == NULL) { return; } tmpNode1 = head; while(tmpNode1) { tmpNode2 = tmpNode1->next; free(tmpNode1); tmpNode1 = tmpNode2; } head = NULL;}/***** * 主程序 */int main(void){ int choice;//用户选项 int isContinue;//是否继续 pNode head;//链表头 choice = 0; studentNumber = 0; head = NULL; isContinue = 1; do{ printf("************************\n"); printf("欢迎使用学生信息管理系统\n"); printf("************************\n"); printf("主菜单:\n"); printf("1.增加学生信息\n"); printf("2.修改学生信息\n"); printf("3.删除学生信息\n"); printf("4.查询学生信息\n"); printf("5.退出系统\n"); printf("------------------------\n"); printf("已有%d名学生信息\n",studentNumber); printf("------------------------\n"); printf("请输入菜单选项(1-5): "); while((scanf("%d",&choice) != 1) || (choice > 5) || (choice < 1)) { printf("警告:请输入1-5整数!\n"); printf("请输入菜单选项(1-5): "); fflush(stdin);//刷新缓冲区 } switch(choice) { case 1://增加 head = add_student(head); break; case 2://修改 modify_student(head); break; case 3://删除 head = delete_student(head); break; case 4://查询 search_student(head); break; case 5://退出系统 quit_student(head); isContinue = 2; break; default://异常错误,暂无处理 printf("出现异常错误,退出系统!\n"); break; } }while(isContinue == 1); return 0;}
- 数据结构之链表的使用【C语言】
- c语言数据结构之链表
- 数据结构之c语言链表
- C语言数据结构之双向链表
- C 语言 数据结构之双向链表
- c语言数据结构之通用链表
- C语言实现数据结构的链表
- 数据结构 链表的实现(C语言)
- C语言数据结构 链表的合并
- C语言之数据结构
- C语言之数据结构
- 数据结构之---c语言实现线性表的顺序表
- C语言数据结构之:顺序表的实现
- C语言数据结构之线性表的基本操作
- 数据结构之队列的实现(c语言)
- 数据结构之c语言栈的演示
- C语言数据结构之单链表的拆分
- C语言数据结构之图的遍历
- [Autofac]组件创建
- MicroStrategy准确控制报表null值显示
- java-第五天
- CentOS Linux解决Device eth0 does not seem to be present
- hdu-2086 A1 = ?
- 数据结构之链表的使用【C语言】
- android---0001
- Oracle 11.2.0.1 升级到 11.2.0.3 示例
- 编译linux内核初体验
- ZOJ 2526 FatMouse and JavaBean II
- vc中加花
- 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用
- node.js 计划任务模块
- Bad vesion 严重: Context initialization failed