赞
踩
大一,刚开始学数据结构,用c语言浅浅写了一个简单的学生信息管理系统
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- typedef struct Student
- {
- int id;
- char name[10];
- }Student;
- typedef struct LNode
- {
- Student stu;
- struct LNode *next;
- }LNode,*LinkList; //LNode等价于struct LNode,LinkList等价于struct LNode* ,即LinkList 与LNode* 两种写法等价,都是表示一个指向结构体的指针类型
- //创建单链表
- void initLinkList(LNode* list); //list就是一个节点,函数头中的list均为形参,只是表示一个LNode类型的指针变量
- //录入数据
- void insertList(LNode* list);
- //展示数据
- void showList(LNode* list);
- //删除数据
- void deleStudent(LNode* list);
- //查找数据
- void getStudent(LNode* list,int i);
- //根据学号查找学生数据
- LNode* getStudentInform(LNode* list,int id);
- //根据姓名查找学生数据
- LNode* getStudentName(LNode* list,char name[10]);
- //删除最后元素
- void deleLastStudent(LNode* list);
- //后插操作
- void insertFromLastById(LNode* list,int i);
- //插入数据(按位插入)
- void insertData(LNode* list);
- //插入数据(按学号插)
- void insertNextNode(LNode* list);
- //插入数据(按姓名插)
- void insertNextName(LNode* list);
- //更新数据
- void updataStudent(LNode* list,int i);
-
- int main()
- {
- LinkList list=(LinkList)malloc(sizeof(LNode));
- initLinkList(list);//创建单链表
- while(1){
- printf("-------------------------------------------------------\n");
- printf("---------------------菜 单-------------------\n");
- printf("-------------------------------------------------------\n");
- 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");
- int flag;
- scanf("%d",&flag);
- int i=0;
- switch(flag){
- case 0:
- printf("正在退出......\n");
- return 0;
- case 1:
- insertList(list);//录入数据
- break;
- case 2:
- showList(list);//展示数据
- break;
- case 3:
- deleStudent(list);//删除数据
- break;
- case 4:
- printf("请输入查找方式:\n");
- printf("1、按学号查找\n");
- printf("2、按姓名查找\n");
- scanf("%d",&i);
- if(i==1||i==2){
- getStudent(list,i);
- }else{
- printf("您输入的方式有误!\n");
- }
- i=0;
- break;
- case 5:
- printf("请输入修改方式:\n");
- printf("1、按学号修改\n");
- printf("2、按姓名修改\n");
- scanf("%d",&i);
- if(i==1||i==2){
- updataStudent(list,i);
- }else{
- printf("您输入的方式有误!\n");
- }
- i=0;
- break;
- case 6:
- printf("请输入插入方式:\n");
- printf("1、按学号插入\n");
- printf("2、按姓名插入\n");
- printf("3、按位置插入\n");
- scanf("%d",&i);
- if(i==1){
- insertNextNode(list);//插入数据(按学号插)
- }else if(i==2){
- insertNextName(list);//插入数据(按姓名插)
- }else if(i==3){
- insertData(list);//插入数据(按位插入)
- }else{
- printf("您输入的方式有误!\n");
- }
- i=0;
- break;
- default:
- printf("您输入的操作序号有误!请重新输入!\n");
- }
- }
- return 0;
- }
- //创建单链表
- void initLinkList(LNode* list)
- {
- list->next=NULL; //指针初始化
- }
- //录入数据
- void insertList(LNode* list)
- {
- LNode* r; //定义尾指针
- r=list;
- int n;
- printf("请输入要录入数据的个数:\n");
- scanf("%d",&n);
- printf("请输入要录入的学生的学号和姓名:\n");
- while(n--){ //循环进行n次
- LNode* p=(LNode*)malloc(sizeof(LNode)); //malloc 函数返回的是 void * 类型, malloc的返回值是一个指向空间首地址的指针,如果分配成功,返回一个非空指针。因此要进行类型转换
- if(p==NULL){ //p是指向新创建的节点的指针
- return;
- }
- scanf("%d%s",&p->stu.id,p->stu.name);
- p->next=NULL;
- r->next=p; //把p的指针域赋值为null,原来尾指针指向p,这样就将p成功链接到头指针后面了
- r=p; //此时p就成了尾指针,把r地址修改成p
- }
- printf("录入数据成功!\n");
- }
- //展示数据
- void showList(LNode* list)
- {
- if(list->next==NULL){
- printf("对不起,您没有输入数据!\n");
- return;
- }
- LNode* p=list->next; // list->next中存放的是地址,只能将地址赋给一个指针变量
- while(p!=NULL){
- printf("学号:%d,姓名:%s\n",p->stu.id,p->stu.name);
- p=p->next;
- }
-
- }
- //查找数据
- void getStudent(LNode* list,int i)
- {
- if(list->next==NULL){
- printf("对不起,您没有输入数据!\n");
- return;
- }
- LNode* p=NULL;
- if(i==1){
- int id;
- printf("请输入要查找的学号:\n");
- scanf("%d",&id);
- p=getStudentInform(list,id);
- }else{
- printf("请输入要查找的姓名:\n");
- char name[10];
- scanf("%s",name);
- p=getStudentName(list,name);
- }
- if(p){
- printf("查找成功!\n");
- printf("学号:%d,姓名:%s\n",p->stu.id,p->stu.name);
- }
- }
- //根据学号查找学生数据
- LNode* getStudentInform(LNode* list,int id)
- {
- LNode* p=list->next;
- while(p!=NULL&&p->stu.id!=id){
- p=p->next;
- }
- if(p==NULL){
- printf("您输入的学号有误!\n");
- }
- return p;
- }
- //根据姓名查找学生数据
- LNode* getStudentName(LNode* list,char name[10])
- {
- LNode* p=list->next;
- while(p!=NULL&&strcmp(p->stu.name,name)!=0){
- p=p->next;
- }
- if(p==NULL){
- printf("您输入的姓名有误!\n");
- }
- return p;
- }
-
- //删除数据
- void deleStudent(LNode* list)
- {
- if(list->next==NULL){
- printf("对不起,您没有输入数据!\n");
- return;
- }
- printf("请输入要删除的学生学号:\n");
- int id;
- scanf("%d",&id);
- //查找学生数据,根据学号,返回节点p
- LNode* p=getStudentInform(list,id);
- //如果删除的节点是最后一个就要遍历
- if(p->next==NULL){
- deleLastStudent(list);
- return;
- }
- LNode* q=p->next; //q是指针,不是q是LNode类型,是q指向LNode类型的变量
- p->stu=q->stu; //删除的本质就是复制后一个节点的数据将要删除节点的数据覆盖,并将要删除节点的指针域改为指向后面第二个节点,相当于将后一个节点内容复制给要删除节点之后,跨过后一个节点,去连接后面第二个节点
- /*q=q->next;q只是一个临时指针后面不会用到,这样写没用,要达到删除的效果应该修改p,为节省空间释放q(不必须)*/
- p->next=q->next;
- free(q);
- printf("删除成功!\n");
- showList(list);
- }
-
- //删除最后元素
- void deleLastStudent(LNode* list)
- {
- LNode* s=list;
- LNode* pt=s->next; //采用双指针的办法
- while(pt->next!=NULL){
- s=s->next;
- pt=s->next;
- }
- s->next=pt->next;
- printf("删除成功!\n");
- showList(list); //因为在函数中还要再次用到指针变量 list,因此引入和 list完全等价的指针变量 s,从而使list的值保持不变
- }
- //插入数据(按位插入)
- void insertData(LNode* list)
- {
- if(list->next==NULL){
- printf("对不起,您没有输入数据!\n");
- return;
- }
- printf("请输入要插入数据的位置:\n");
- int i;
- scanf("%d",&i);
- //创建函数进行后插操作
- insertFromLastById(list,i);
- showList(list);
- }
- //后插操作
- void insertFromLastById(LNode* list,int i)
- {
- LNode* p=list;
- int j=0;
- while(p!=NULL&&j<i-1){
- p=p->next;
- j++;
- }
- if(p==NULL){
- printf("您输入的位置有误!\n");
- return;
- }
- LNode* s=(LinkList)malloc(sizeof(LNode));
- printf("请输入要插入学生的学号和姓名:\n");
- scanf("%d%s",&s->stu.id,s->stu.name);
- s->next=p->next;
- p->next=s;
- printf("插入成功!\n");
- }
- //插入数据(按学号插)
- void insertNextNode(LNode* list)
- {
- if(list->next==NULL){
- printf("对不起,您没有输入数据!\n");
- return;
- }
- printf("请输入要在哪个学号后插入:\n");
- int id;
- scanf("%d",&id);
- LNode* p=getStudentInform(list,id);
- LNode* s=(LinkList)malloc(sizeof(LNode));
- printf("请输入要插入学生的学号和姓名:\n");
- scanf("%d%s",&s->stu.id,s->stu.name);
- s->next=p->next;
- p->next=s;
- printf("插入成功!\n");
- showList(list);
- }
- //插入数据(按姓名插)
- void insertNextName(LNode* list)
- {
- if(list->next==NULL){
- printf("对不起,您没有输入数据!\n");
- return;
- }
- printf("请输入要在哪个姓名后插入:\n");
- char name[10];
- scanf("%s",name);
- LNode* p=getStudentName(list,name);
- LNode* s=(LinkList)malloc(sizeof(LNode));
- printf("请输入要插入学生的学号和姓名:\n");
- scanf("%d%s",&s->stu.id,s->stu.name);
- s->next=p->next;
- p->next=s;
- printf("插入成功!\n");
- showList(list);
- }
-
- //更新数据
- void updataStudent(LNode* list,int i)
- {
- if(list->next==NULL){
- printf("对不起,您没有输入数据!\n");
- return;
- }
- LNode* p=NULL;
- if(i==1){
- printf("请输入要更改的学生的学号:\n");
- int id;
- scanf("%d",&id);
- p=getStudentInform(list,id);
- }else{
- printf("请输入要更改的学生的姓名:\n");
- char name[10];
- scanf("%s",name);
- p=getStudentName(list,name);
- }
- if(p){
- printf("请重新输入学生的学号和姓名:\n");
- scanf("%d%s",&p->stu.id,p->stu.name);
- printf("修改成功!\n");
- showList(list);
- }
-
- }

有参考别人的写法,也加了自己的东西到里面,是一边写一边改进的,写到后面不想改了,所以删除只用了学号查找这一种方式
以及我没有考虑按姓名查找若有重名的情况,因此按姓名查询得到只有最前面符合条件的一条结果
还有就是录入姓名用的scanf,英文名有空格的情况就不适用
刚学,有瑕疵,且作分享,还请多多指教hhh
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。