1 数据结构
是指所有 数据元素 及 数据元素之间 的关系。
1.1 逻辑关系(结构)类型
(1)集合;(2)线性结构;(3)树形结构;(4)图形结构。
1.2 存储方式(结构)类型
(1)顺序存储结构;(2)链式存储结构;(3)索引存储结构;(4)散列(哈希)存储结构。
2 算法
算法时对特定问题的求解步骤的一种描述。
3 算法 (效率与存储空间) 分析
3.1 时间复杂度
一个算法的执行时间可以由其中基本运算的执行次数T(n) 来计量。
3.2 空间复杂度
在对算法进行存储空间分析时,只考虑辅助变量的所占空间。
4 数据结构对算法的影响
4.1 设计方案1:
将学生的全部数据放在一个表中,一个学生的全部数据对应一条记录。方案分析:存在一定的存储空间浪费,因为没有选修的课程,对应的成绩没有意义(-1来表示),allavg算法的时间复杂度为O(n)。
#include <stdio.h>
#define MaxStud 50 //学生人数最多为50
struct stud
{
int no; //学号
char name[10]; //姓名
int bno; //班号
int deg1; //课程1分数
int deg2; //课程2分数
int deg3; //课程3分数
int deg4; //课程4分数
int deg5; //课程5分数
int deg6; //课程6分数
};
double studavg(struct stud s[], int i) //求s[i]学生的平均分
{
int m = 0; //s[i]学生选学课程数
double sum = 0; //s[i]学生总分
if (s[i].deg1 != -1)
{
m++;
sum += s[i].deg1;
}
if (s[i].deg2 != -1)
{
m++;
sum += s[i].deg2;
}
if (s[i].deg3 != -1)
{
m++;
sum += s[i].deg3;
}
if (s[i].deg4 != -1)
{
m++;
sum += s[i].deg4;
}
if (s[i].deg5 != -1)
{
m++;
sum += s[i].deg5;
}
if (s[i].deg6 != -1)
{
m++;
sum += s[i].deg6;
}
return(sum / m);
}
double couravg(struct stud s[], int n, int i) //求第i门课程的平均分
{
int j, m = 0; //m为第i门课程选修人数
double sum = 0; //第i门课程总分
switch (i)
{
case 1:for (j = 0;j < n;j++)
if (s[j].deg1 != -1)
{
m++;
sum += s[j].deg1;
}
break;
case 2:for (j = 0;j < n;j++)
if (s[j].deg2 != -1)
{
m++;
sum += s[j].deg2;
}
break;
case 3:for (j = 0;j < n;j++)
if (s[j].deg3 != -1)
{
m++;
sum += s[j].deg3;
}
break;
case 4:for (j = 0;j < n;j++)
if (s[j].deg4 != -1)
{
m++;
sum += s[j].deg4;
}
break;
case 5:for (j = 0;j < n;j++)
if (s[j].deg5 != -1)
{
m++;
sum += s[j].deg5;
}
break;
case 6:for (j = 0;j < n;j++)
if (s[j].deg6 != -1)
{
m++;
sum += s[j].deg6;
}
break;
}
return(sum / m);
}
void allavg(struct stud s[], int n) //求学生平均分和课程平均分
{
int i;
printf("学生平均分:\n");
printf(" 学号 姓名 平均分\n");
for (i = 0;i < n;i++)
{
printf("%4d %10s %g\n", s[i].no, s[i].name, studavg(s, i));
}
printf("课程平均分:\n");
for (i = 1;i <= 6;i++)
printf(" 课程%d:%g\n", i, couravg(s, n, i));
}
int main()
{
int n = 7; //学生记录个数
struct stud s[MaxStud] = {
{1,"张斌",9901,67,98,-1,65,-1,-1},
{8,"刘丽",9902,98,-1,90,-1,67},
{34,"李英",9901,-1,56,-1,65,-1,77},
{20,"陈华",9902,68,92,64,-1,-1,-1},
{12,"王奇",9901,-1,-1,-1,76,75,78},
{26,"董强",9902,67,-1,-1,-1,78,62},
{5,"王萍",9901,94,92,-1,-1,-1,89} };
allavg(s, n);
}
4.2 方案设计2:
将学生的全部数据项放在一个表中,但一个学生的一门课程成绩对应一条记录。方案分析:存在大量的存储空间冗余,allavg算法的时间复杂度为O(n^2)。
#include <stdio.h>
#define MaxCour 300 //学生成绩记录数最多为50*6
struct stud
{
int no; //学号
char name[10]; //姓名
int bno; //班号
int cno; //课程编号
int deg; //课程分数
};
double studavg(struct stud s[], int n, int i) //求学号为i的学生的平均分
{
int j, m = 0; //m为学号为i的学生选学课程数
double sum = 0; //学号为i的学生总分
for (j = 0;j < n;j++)
if (s[j].no == i) //学号为i时统计
{
m++;
sum += s[j].deg;
}
return(sum / m);
}
double couravg(struct stud s[], int n, int i) //求编号为i的课程的平均分
{
int j, m = 0; //m为编号为i的课程选修人数
double sum = 0; //编号为i的课程总分
for (j = 0;j < n;j++)
{
if (s[j].cno == i) //课程编号为i时统计
{
m++;
sum += s[j].deg;
}
}
return(sum / m);
}
void allavg(struct stud s[], int n) //求学生平均分和课程平均分
{
int i, j;
printf("学生平均分:\n");
printf("学号姓名平均分\n");
i = 0;
while (i < n)
{
j = s[i].no;
printf("%4d %10s %g\n", s[i].no, s[i].name, studavg(s, n, j));
i++;
while (s[i].no == j) //若下一个记录与上一个记录学号相同,跳过该记录
i++;
}
printf("课程平均分:\n");
for (i = 1;i <= 6;i++)
printf("课程%d:%g \n ",i,couravg(s,n,i));
}
int main()
{
int n = 21; //学生记录个数
struct stud s[MaxCour] = { //规定课程的编号从1到6,同一学生记录连续存放
{1,"张斌",9901,1,67},
{1,"张斌",9901,2,98},
{1,"张斌",9901,4,65},
{8,"刘丽",9902,1,98},
{8,"刘丽",9902,3,90},
{8,"刘丽",9902,6,67},
{34,"李英",9901,2,56},
{34,"李英",9901,4,65},
{34,"李英",9901,6,77},
{20,"陈华",9902,1,68},
{20,"陈华",9902,2,92},
{20,"陈华",9902,3,64},
{12,"王奇",9901,4,76},
{12,"王奇",9901,5,75},
{12,"王奇",9901,6,78},
{26,"董强",9902,1,67},
{26,"董强",9902,5,78},
{26,"董强",9902,6,62},
{5,"王萍",9901,1,94},
{5,"王萍",9901,2,92},
{5,"王萍",9901,6 ,89}};
allavg(s, n);
}
4.3 设计方案3:
将学生的学号、姓名和班号放在一个表中,将成绩数据放在另一个表中,两者通过学号关联。算法分析:节省空间,allavg算法的时间复杂度为O(n×m),其中,n为学生人数,m为学生成绩记录个数。
#include <stdio.h>
#define MaxStud 50 //学生人数最多为50
#define MaxCour 300 //学生成绩记录数最多为50*6
struct stud1
{
int no; //学号
char name[10]; //姓名
int bno; //班号
};
struct stud2
{
int no; //学号
int cno; //课程编号
int deg; //分数
};
double studavg(struct stud2 s2[], int m, int i) //求学号为i的学生的平均分
{
int j, n = 0; //n为学号为i的学生选学课程数
double sum = 0; //学号为i的学生总分
for (j = 0;j < m;j++)
if (s2[j].no == i) //学号为i时统计
{
n++;
sum += s2[j].deg;
}
return(sum / n);
}
double couravg(struct stud2 s2[], int m, int i) //求编号为i的课程的平均分
{
int j, n = 0; //n为编号为i的课程选修人数
double sum = 0; //编号为i的课程总分
for (j = 0;j < m;j++)
{
if (s2[j].cno == i) //课程编号为i时统计
{
n++;
sum += s2[j].deg;
}
}
return(sum / n);
}
void allavg(struct stud1 s1[], int n, struct stud2 s2[], int m) //求学生平均分和课程平均分
{
int i, j;
printf("学生平均分:\n");
printf(" 学号 姓名 平均分\n");
i = 0;
while (i < n)
{
j = s1[i].no;
printf("%4d %10s %g\n", s1[i].no, s1[i].name, studavg(s2, m, j));
i++;
}
printf("课程平均分:\n");
for (i = 1;i <= 6;i++)
printf(" 课程%d:%g\n",i,couravg(s2,m,i));
}
int main()
{
int n = 7; //学生记录人数
int m = 21; //学生成绩记录数
struct stud1 s1[MaxStud] = {
{1,"张斌",9901},
{8,"刘丽",9902},
{34,"李英",9901},
{20,"陈华",9902},
{12,"王奇",9901},
{26,"董强",9902},
{5,"王萍",9901}};
struct stud2 s2[MaxCour] = { //规定课程的编号从1到6,同一学生成绩记录连续存放
{1,1,67},
{1,2,98},
{1,4,65},
{8,1,98},
{8,3,90},
{8,6,67},
{34,2,56},
{34,4,65},
{34,6,77},
{20,1,68},
{20,2,92},
{20,3,64},
{12,4,76},
{12,5,75},
{12,6,78},
{26,1,67},
{26,5,78},
{26,6,62},
{5,1,94},
{5,2,92},
{5,6,89} };
allavg(s1, n, s2, m);
}
4.4 运行结果
4.5 方案分析
方案 | 存储空间 | 执行时间 | 算法简洁性 | 综合评价 |
---|---|---|---|---|
方案1 | 中 | 好 | 差 | 差 |
方案2 | 差 | 差 | 好 | 中 |
方案3 | 好 | 中 | 好 | 好 |