最后,将写完的代码贴上来
一点说明:
1、目前还有一些bug,在ID被判重复后输入0,有时会使得程序崩溃,时间原因尚未解决
2、中英文的注释混杂,并不是一个好习惯。写的过程中试图让自己以全英文注释,并严格按格式注释。但由于时间关系或英文水平的限制,既没有按照格式来注释,也没有做到全英文。
3、链表的建立、validate并不是很让我满意,感觉还有可以优化的地方。
4、sort用了选择排序,find只是逐个比较来查找,并没有学到什么新的算法,也没有搜一搜适合链表的查找算法。这里或许可以做很多优化。
5、文件的读写过于频繁。还不会随机读写,或许这里也可以进一步优化。
6、之所以主界面里面没有单独的排序功能,是因为添加、更新数据后都会重新排序一次并保存在文件中。
7、交互界面并不令我满意。很简陋。
8、在前期没有把函数的实现方法想明白,导致main.c中controller函数很复杂。或许可以改进一下delete、update等函数,使得代码更简洁,重复代码更少。并且使得variance、delete、update等函数用法更加一致。
9、程序写完之后才意识到没有输出均值,于是临时添加全局变量m_ave。
10、在学生姓名发生重复时,无法同时查找到这些学生。
——————————————
20170508修复了update时无法更新的问题。
——————————————
20170520结构体可以用=直接赋值,可以将swap函数省略了但还没有改
——————————————
app.c
#include "final.h"
/**
*selectsort by cls & sub-by name
*by cantjie
*/
stu *sort(stu *head)
{
//遍历链表,每次找出一个最小的节点,将其值与未排序节点的首个节点交换,这里需要一个指针标记值最小的节点。
stu *p1, *p2, *min;
for (p1 = head->next; p1->next != NULL; p1 = p1->next)
{
min = p1;
for (p2 = p1->next; p2; p2 = p2->next)//由前向后遍历,找出最小的节点
{
if (p2->cls<min->cls)
min = p2;
else
{
if (p2->cls == min->cls)
{
if (strcmp(p2->name, p1->name) < 0)
{
swapStu(p1, p2);
}
}
}
}
if (min != p1)
swapStu(p1, min);
}
saveStu(head->next, 0);
m_head = head;
return head;
}
/**
*检查id 是否重复,如果id重复,返回1。不重复返回0
*/
int validate(stu *head, int id)
{
stu *p = head;
int flag = 0;//因为会遇到自己,设置一个flag,当flag为2时表示有重复;
while (p->next)
{
if (p->next->id == id)
{
if (flag)
return 1;
flag++;
}
p = p->next;
}
if (m_head != head)
{
p = m_head;
if (p == NULL)
return 0;
while (p->next)
{
if (p->next->id == id)
return 1;
else
p = p->next;
}
return 0;
}
}
/**
*计算方差,包含三种格式:
*1、输入0,返回所有学生方差;
*2、输入1,输入cls,返回该班学生的方差;
*3、输入2,然后输入id范围,返回方差;
*by cantjie
*/
float varianceStu(stu *head)
{
int flag = -1;
int n = 0;
int idmax=0, idmin=0;//for case 2
int id = 0;//for case 3
float var=0, sum=0, ave=0;
int i = 0;
stu *p = head;
printf("\ninput 0 to get all students' variance");
printf("\ninput 1 to get variance of students of a class");
printf("\ninput 2 to get varicance of students of a range of ids\n");
scanf("%d", &flag);
switch (flag)
{
case 0://全体方差
for (i = 0; i < m_n; i++)
{
sum += p->next->sum;
p = p->next;
}
ave = sum / m_n;
p = head;
for (i = 0; i < m_n; i++)
{
var += (p->next->sum - ave)*(p->next->sum - ave);
p = p->next;
}
var /= m_n;
break;
case 1://返回班级方差
printf("\nPlease input class:");
int cls = 0;
scanf("%d", &cls);
for (i = 0; i < m_n; i++)
{
if (p->next->cls == cls)
{
sum += p->next->sum;
n++;
}
p = p->next;
}
ave = sum / n;
p = head;
for (i = 0; i < m_n; i++)
{
if (p->next->cls == cls)
{
var += (p->next->sum - ave)*(p->next->sum - ave);
}
p = p->next;
}
var /= n;
break;