学生成绩管理项目-第一周:基本类型链表操作
终于每周折腾开始了!第一个要处理的项目就是经典的学生成绩管理系统了。C的经典期末测试题!
不过这次我决定作个死折腾一下。用链表来实现这个项目。那么将目标分解一下吧!分为三周去解决
第一周:基本类型链表,实现功能:排序,遍历,插入,删除,查找。
第二周:结构体链表、对象链表和STL list类
第三周:添加所需功能封装成类。
第四周:完善界面制作成品。
废话不多说开始第一周的工程。基本的链表操作!
就从最基本的int链表开始吧。也不写类。就用最简单的结构体方式来实现 插入 删除 排序 遍历等功能。
数据结构的基本挑战即将开始!
---------传说中的分割线----------
折腾了这么久 都2周总算搞出来了 那么现在就贴一下代码 不得不说链表还是不好搞的!
# include<iostream> using namespace std; struct node { int data; struct node * next; };//创建结构体。 /* create函数:创建一个节点数为n的链表 并返回指向链表表头的指针(即头指针) */ struct node * create(int n)//n为节点数 { struct node * phead=NULL;//表头指针 struct node * p1=NULL;//指向当前生成的结点的指针 struct node * p2=NULL;//指向上一个生成的节点,当新节点生成时,利用该指针将上一个节点的next指针指向新生成的节点 int a;//存放临时变量 for (int i = 1; i <= n; i++) { p1 = new struct node;//动态分配一个空间给新节点 printf("please enter the value of node %d:",i); scanf_s("%d",&a); p1->data = a; p1->next = NULL;//新生成的节点的next指针应为空 if (i == 1) phead = p1; else p2->next = p1; /*如果是第一个节点就把头指针指向该节点,否则就把上一个节点的next指针指向当前结点*/ p2 = p1;//p2保存当前结点的地址,以便下个节点使用 } return phead; } void traverse_print(struct node * phead) { struct node * walker; int i = 1; walker = phead; while (walker != NULL) { printf("The value of node %d is %d\n",i,walker->data); walker = walker->next; i++; } } /* 删除一个节点的函数: 我们务必搞明白指针之间的关系 首先 函数拿到的是头指针的值。如果你要删除的不是头节点,那么我们因为拿到了头指针的值而得以搜索链表 使用p1,p2两个指针我们可以指向链表中的两个节点。这样就可以修改链表的值。 但是如果删除的是头节点。就以为着要修改头指针的值,但是我们没有办法得到一个指向头指针的指针来修改 头指针的值。于是采用一种折中的办法。我们让函数把删除操作完成后的形参的值返回给头指针。 */ struct node * deletenode(struct node * phead,int n) { struct node * p1 = phead; struct node * p2 = NULL; if (n == 1) { phead = phead->next; } else { for (int i = 1; i < n; i++) { p2 = p1; p1 = p1->next; } p2->next = p1->next; delete(p1); } return phead; } struct node * insertnode(struct node * phead, int n) { struct node * p1 = NULL; struct node * p2 = NULL; if (n == 1) { p2 = phead; p1 = new struct node; printf("Please enter the value of the new node:"); scanf_s("%d",&p1->data); phead = p1; p1->next = p2; } else { p2 = phead; for (int i = 1; i < n; i++) { p2 = p2->next; }//让p2指向第n-1个节点 p1 = new struct node; printf("Please enter the value of the new node:"); scanf_s("%d",&p1->data); p1->next = p2->next; p2->next = p1; } return phead; } /* 有关链表的排序:链表和数组一样都是线性的数据结构因此排序算法并无区别。 用最简单的冒泡来演示一下:需要注意的一点是 你只需要互换两个节点的数据域 而不是将两个结点的储存空间互换 */ struct node * buble_sort(struct node * phead) { int temp; struct node * p1 = NULL; struct node * p2 = NULL; for (p1 = phead; p1 != NULL; p1 = p1->next) { for (p2 = p1; p2 != NULL; p2 = p2->next) { if (p1->data > p2->data) { temp = p1->data; p1->data = p2->data; p2->data = temp; } } } return phead; } int main() { int n; struct node * mylist=NULL; printf("Please enter the total number of nodes you nead to create:"); scanf_s("%d",&n); mylist = create(n); printf("Now you can operate your list.\n"); A: printf("select a option:\n"); printf("1.print\n"); printf("2.delete node\n"); printf("3.insert node\n"); printf("4.sort:A-Z\n"); int op; scanf_s("%d",&op); switch (op) { case 1: { traverse_print(mylist); break; } case 2: { if (mylist == NULL) { printf("Error!The list is empty now!!\n"); break; } printf("please enter the number of node you want to delete\n"); int d; scanf_s("%d", &d); mylist = deletenode(mylist,d); printf("No. %d node had been deleted\n",d); break; } case 3: { printf("Please enter the position you want to insert the new node:"); int i; scanf_s("%d",&i); mylist = insertnode(mylist, i); printf("The new node has been inserted.\n"); break; } case 4: { mylist = buble_sort(mylist); printf("Sort Compelted!\n"); } } goto A; system("pause"); return 0; }