当前位置:   article > 正文

单链表简单学生信息管理系统(纯C语言实现)_数据结构c单链表学分管理

数据结构c单链表学分管理

大一,刚开始学数据结构,用c语言浅浅写了一个简单的学生信息管理系统

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef struct Student
  5. {
  6. int id;
  7. char name[10];
  8. }Student;
  9. typedef struct LNode
  10. {
  11. Student stu;
  12. struct LNode *next;
  13. }LNode,*LinkList; //LNode等价于struct LNode,LinkList等价于struct LNode* ,即LinkList 与LNode* 两种写法等价,都是表示一个指向结构体的指针类型
  14. //创建单链表
  15. void initLinkList(LNode* list); //list就是一个节点,函数头中的list均为形参,只是表示一个LNode类型的指针变量
  16. //录入数据
  17. void insertList(LNode* list);
  18. //展示数据
  19. void showList(LNode* list);
  20. //删除数据
  21. void deleStudent(LNode* list);
  22. //查找数据
  23. void getStudent(LNode* list,int i);
  24. //根据学号查找学生数据
  25. LNode* getStudentInform(LNode* list,int id);
  26. //根据姓名查找学生数据
  27. LNode* getStudentName(LNode* list,char name[10]);
  28. //删除最后元素
  29. void deleLastStudent(LNode* list);
  30. //后插操作
  31. void insertFromLastById(LNode* list,int i);
  32. //插入数据(按位插入)
  33. void insertData(LNode* list);
  34. //插入数据(按学号插)
  35. void insertNextNode(LNode* list);
  36. //插入数据(按姓名插)
  37. void insertNextName(LNode* list);
  38. //更新数据
  39. void updataStudent(LNode* list,int i);
  40. int main()
  41. {
  42. LinkList list=(LinkList)malloc(sizeof(LNode));
  43. initLinkList(list);//创建单链表
  44. while(1){
  45. printf("-------------------------------------------------------\n");
  46. printf("---------------------菜 单-------------------\n");
  47. printf("-------------------------------------------------------\n");
  48. printf("---------------------请输入操作序号:------------------\n");
  49. printf("---------------------1、录入学生信息-------------------\n");
  50. printf("---------------------2、展示学生信息-------------------\n");
  51. printf("---------------------3、删除学生信息-------------------\n");
  52. printf("---------------------4、查询学生信息-------------------\n");
  53. printf("---------------------5、修改学生信息-------------------\n");
  54. printf("---------------------6、插入学生信息-------------------\n");
  55. printf("---------------------0、退 出-------------------\n");
  56. printf("-------------------------------------------------------\n");
  57. int flag;
  58. scanf("%d",&flag);
  59. int i=0;
  60. switch(flag){
  61. case 0:
  62. printf("正在退出......\n");
  63. return 0;
  64. case 1:
  65. insertList(list);//录入数据
  66. break;
  67. case 2:
  68. showList(list);//展示数据
  69. break;
  70. case 3:
  71. deleStudent(list);//删除数据
  72. break;
  73. case 4:
  74. printf("请输入查找方式:\n");
  75. printf("1、按学号查找\n");
  76. printf("2、按姓名查找\n");
  77. scanf("%d",&i);
  78. if(i==1||i==2){
  79. getStudent(list,i);
  80. }else{
  81. printf("您输入的方式有误!\n");
  82. }
  83. i=0;
  84. break;
  85. case 5:
  86. printf("请输入修改方式:\n");
  87. printf("1、按学号修改\n");
  88. printf("2、按姓名修改\n");
  89. scanf("%d",&i);
  90. if(i==1||i==2){
  91. updataStudent(list,i);
  92. }else{
  93. printf("您输入的方式有误!\n");
  94. }
  95. i=0;
  96. break;
  97. case 6:
  98. printf("请输入插入方式:\n");
  99. printf("1、按学号插入\n");
  100. printf("2、按姓名插入\n");
  101. printf("3、按位置插入\n");
  102. scanf("%d",&i);
  103. if(i==1){
  104. insertNextNode(list);//插入数据(按学号插)
  105. }else if(i==2){
  106. insertNextName(list);//插入数据(按姓名插)
  107. }else if(i==3){
  108. insertData(list);//插入数据(按位插入)
  109. }else{
  110. printf("您输入的方式有误!\n");
  111. }
  112. i=0;
  113. break;
  114. default:
  115. printf("您输入的操作序号有误!请重新输入!\n");
  116. }
  117. }
  118. return 0;
  119. }
  120. //创建单链表
  121. void initLinkList(LNode* list)
  122. {
  123. list->next=NULL; //指针初始化
  124. }
  125. //录入数据
  126. void insertList(LNode* list)
  127. {
  128. LNode* r; //定义尾指针
  129. r=list;
  130. int n;
  131. printf("请输入要录入数据的个数:\n");
  132. scanf("%d",&n);
  133. printf("请输入要录入的学生的学号和姓名:\n");
  134. while(n--){ //循环进行n次
  135. LNode* p=(LNode*)malloc(sizeof(LNode)); //malloc 函数返回的是 void * 类型, malloc的返回值是一个指向空间首地址的指针,如果分配成功,返回一个非空指针。因此要进行类型转换
  136. if(p==NULL){ //p是指向新创建的节点的指针
  137. return;
  138. }
  139. scanf("%d%s",&p->stu.id,p->stu.name);
  140. p->next=NULL;
  141. r->next=p; //把p的指针域赋值为null,原来尾指针指向p,这样就将p成功链接到头指针后面了
  142. r=p; //此时p就成了尾指针,把r地址修改成p
  143. }
  144. printf("录入数据成功!\n");
  145. }
  146. //展示数据
  147. void showList(LNode* list)
  148. {
  149. if(list->next==NULL){
  150. printf("对不起,您没有输入数据!\n");
  151. return;
  152. }
  153. LNode* p=list->next; // list->next中存放的是地址,只能将地址赋给一个指针变量
  154. while(p!=NULL){
  155. printf("学号:%d,姓名:%s\n",p->stu.id,p->stu.name);
  156. p=p->next;
  157. }
  158. }
  159. //查找数据
  160. void getStudent(LNode* list,int i)
  161. {
  162. if(list->next==NULL){
  163. printf("对不起,您没有输入数据!\n");
  164. return;
  165. }
  166. LNode* p=NULL;
  167. if(i==1){
  168. int id;
  169. printf("请输入要查找的学号:\n");
  170. scanf("%d",&id);
  171. p=getStudentInform(list,id);
  172. }else{
  173. printf("请输入要查找的姓名:\n");
  174. char name[10];
  175. scanf("%s",name);
  176. p=getStudentName(list,name);
  177. }
  178. if(p){
  179. printf("查找成功!\n");
  180. printf("学号:%d,姓名:%s\n",p->stu.id,p->stu.name);
  181. }
  182. }
  183. //根据学号查找学生数据
  184. LNode* getStudentInform(LNode* list,int id)
  185. {
  186. LNode* p=list->next;
  187. while(p!=NULL&&p->stu.id!=id){
  188. p=p->next;
  189. }
  190. if(p==NULL){
  191. printf("您输入的学号有误!\n");
  192. }
  193. return p;
  194. }
  195. //根据姓名查找学生数据
  196. LNode* getStudentName(LNode* list,char name[10])
  197. {
  198. LNode* p=list->next;
  199. while(p!=NULL&&strcmp(p->stu.name,name)!=0){
  200. p=p->next;
  201. }
  202. if(p==NULL){
  203. printf("您输入的姓名有误!\n");
  204. }
  205. return p;
  206. }
  207. //删除数据
  208. void deleStudent(LNode* list)
  209. {
  210. if(list->next==NULL){
  211. printf("对不起,您没有输入数据!\n");
  212. return;
  213. }
  214. printf("请输入要删除的学生学号:\n");
  215. int id;
  216. scanf("%d",&id);
  217. //查找学生数据,根据学号,返回节点p
  218. LNode* p=getStudentInform(list,id);
  219. //如果删除的节点是最后一个就要遍历
  220. if(p->next==NULL){
  221. deleLastStudent(list);
  222. return;
  223. }
  224. LNode* q=p->next; //q是指针,不是q是LNode类型,是q指向LNode类型的变量
  225. p->stu=q->stu; //删除的本质就是复制后一个节点的数据将要删除节点的数据覆盖,并将要删除节点的指针域改为指向后面第二个节点,相当于将后一个节点内容复制给要删除节点之后,跨过后一个节点,去连接后面第二个节点
  226. /*q=q->next;q只是一个临时指针后面不会用到,这样写没用,要达到删除的效果应该修改p,为节省空间释放q(不必须)*/
  227. p->next=q->next;
  228. free(q);
  229. printf("删除成功!\n");
  230. showList(list);
  231. }
  232. //删除最后元素
  233. void deleLastStudent(LNode* list)
  234. {
  235. LNode* s=list;
  236. LNode* pt=s->next; //采用双指针的办法
  237. while(pt->next!=NULL){
  238. s=s->next;
  239. pt=s->next;
  240. }
  241. s->next=pt->next;
  242. printf("删除成功!\n");
  243. showList(list); //因为在函数中还要再次用到指针变量 list,因此引入和 list完全等价的指针变量 s,从而使list的值保持不变
  244. }
  245. //插入数据(按位插入)
  246. void insertData(LNode* list)
  247. {
  248. if(list->next==NULL){
  249. printf("对不起,您没有输入数据!\n");
  250. return;
  251. }
  252. printf("请输入要插入数据的位置:\n");
  253. int i;
  254. scanf("%d",&i);
  255. //创建函数进行后插操作
  256. insertFromLastById(list,i);
  257. showList(list);
  258. }
  259. //后插操作
  260. void insertFromLastById(LNode* list,int i)
  261. {
  262. LNode* p=list;
  263. int j=0;
  264. while(p!=NULL&&j<i-1){
  265. p=p->next;
  266. j++;
  267. }
  268. if(p==NULL){
  269. printf("您输入的位置有误!\n");
  270. return;
  271. }
  272. LNode* s=(LinkList)malloc(sizeof(LNode));
  273. printf("请输入要插入学生的学号和姓名:\n");
  274. scanf("%d%s",&s->stu.id,s->stu.name);
  275. s->next=p->next;
  276. p->next=s;
  277. printf("插入成功!\n");
  278. }
  279. //插入数据(按学号插)
  280. void insertNextNode(LNode* list)
  281. {
  282. if(list->next==NULL){
  283. printf("对不起,您没有输入数据!\n");
  284. return;
  285. }
  286. printf("请输入要在哪个学号后插入:\n");
  287. int id;
  288. scanf("%d",&id);
  289. LNode* p=getStudentInform(list,id);
  290. LNode* s=(LinkList)malloc(sizeof(LNode));
  291. printf("请输入要插入学生的学号和姓名:\n");
  292. scanf("%d%s",&s->stu.id,s->stu.name);
  293. s->next=p->next;
  294. p->next=s;
  295. printf("插入成功!\n");
  296. showList(list);
  297. }
  298. //插入数据(按姓名插)
  299. void insertNextName(LNode* list)
  300. {
  301. if(list->next==NULL){
  302. printf("对不起,您没有输入数据!\n");
  303. return;
  304. }
  305. printf("请输入要在哪个姓名后插入:\n");
  306. char name[10];
  307. scanf("%s",name);
  308. LNode* p=getStudentName(list,name);
  309. LNode* s=(LinkList)malloc(sizeof(LNode));
  310. printf("请输入要插入学生的学号和姓名:\n");
  311. scanf("%d%s",&s->stu.id,s->stu.name);
  312. s->next=p->next;
  313. p->next=s;
  314. printf("插入成功!\n");
  315. showList(list);
  316. }
  317. //更新数据
  318. void updataStudent(LNode* list,int i)
  319. {
  320. if(list->next==NULL){
  321. printf("对不起,您没有输入数据!\n");
  322. return;
  323. }
  324. LNode* p=NULL;
  325. if(i==1){
  326. printf("请输入要更改的学生的学号:\n");
  327. int id;
  328. scanf("%d",&id);
  329. p=getStudentInform(list,id);
  330. }else{
  331. printf("请输入要更改的学生的姓名:\n");
  332. char name[10];
  333. scanf("%s",name);
  334. p=getStudentName(list,name);
  335. }
  336. if(p){
  337. printf("请重新输入学生的学号和姓名:\n");
  338. scanf("%d%s",&p->stu.id,p->stu.name);
  339. printf("修改成功!\n");
  340. showList(list);
  341. }
  342. }

有参考别人的写法,也加了自己的东西到里面,是一边写一边改进的,写到后面不想改了,所以删除只用了学号查找这一种方式

以及我没有考虑按姓名查找若有重名的情况,因此按姓名查询得到只有最前面符合条件的一条结果

还有就是录入姓名用的scanf,英文名有空格的情况就不适用

刚学,有瑕疵,且作分享,还请多多指教hhh

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/859781
推荐阅读
相关标签
  

闽ICP备14008679号