// 线性表__学生成绩管理.cpp : 此文件包含 “main” 函数。程序执行将在此处开始并结束。
/*
线性表是数据结构中最简单最常用的一种线性结构,也是学习数据结构全部内容的基础,其掌握的好坏直接影响
着后续知识的学习。本章通过四个模拟项目来学习线性表的顺序和链式存储结构,首先通过使用有关数组的操作实现学生成绩管理,其次通过使用有关线性链表的操作实现考试报名管理,然后通关过是用循环链表的操作
实现约瑟夫生者死者游戏。
1.1 学生成绩管理
1.1.1项目简介
学生成绩管理是学校教务部门的日常工作的重要组成部分,其处理信息量很大。本项目是对学生成绩管理的简单模拟,用菜单选择方式完成下列功能:输入学生数据;输出学生数据;学生数据查询;添加学生数据;修改学生数据;删除学生数据。
1.1.2设计思路
本项目的实质是完成对学生成绩信息的建立、查找、插入、修改、删除等功能,可以首先定义项目的数据结构,然后将每个功能写成一个函数来完成对数据的操作,最后完成主函数以验证各个函数功能并得出运行结果。
1.1.3数据结构
本项目的数据十一组学生的成绩信息,每条学生的成绩信息由序号、姓名和成绩来组成,这组学生的成绩信息具有相同特性,属于同一数据对象,相邻数据元素之间存在序偶关系。由此可以看出,这些数据具有线性表中数据元素的性质,所以该系统的数据采用线性表来
存储。
顺序表示线性表的顺序存储结构,是指一组连续的内存单元以此存放线性表的数据元素。在顺序存储结构下,逻辑关系相邻的两个元素在物理位置上也相邻,这是顺序表的特点。本项目可以采用顺序表的线性表顺序存储结构。
若一个数据元素仅占一个存储单元,其存储方式如下:
Loc(ai)=loc(a1)+(i-1)
假设线性表中每个元素占用k个存储单元,那么在顺序表中,线性表的第i个元素的存储位置与第1个元素的存储位置的关系是:
Loc(ai)=loc(a1)+(i-1)*k
这里Loc(ai)是第i个元素的存储位置,loc(a1)是第一个元素的存储位置,也称为线性表的基址。显然,顺序表便于进行随机访问,故线性表的顺序存储结构是一种随机存储结构。
顺序表适宜于做查找这样的静态的操作;顺序存储的优点是存储密度大,存储空间利用率高。缺点是插入或删除元素时不方便。
由于C语言的数组类型也有随机存储的特点,一维数组的机内表示就是顺序结构。因袭,可用C语言的一维数组实现线性表的顺序存储。数组实现的线性表的顺序存储的优点是可以随机存取表中任一元素O(1),存储空间使用紧凑;缺点是在插入,删除某一元素时,需要移动大量元素O(n),预先分配空间按最大空间分配,利用不充分,表容量难以扩充。
用结构体类型定义每个学生数据,故该数组中的每个数据的结构可描述为:
typedef struct STU
{
char stuno[10];//学号
char name[10];//姓名
float score;//成绩
}ElemType;
完整的程序清单:
//1.1.4 程序清单
#include
#include
#include
#include
#include
#include
using namespace std;
#define MaxListSize 20
#define EQUAL 1
typedef struct STU
{
char stuno[10];//学号
char name[10];//姓名
float score;//成绩
int age;
}ElemType;
class List
{
public:
//输入学生的数据:
void init(List **L, int ms);
//删除所有学生数据
void DsatoryList(List &L) { free(&L);}
//将顺序表置为空
void ClearList() { length = 0; }
//判断顺序表是否为空表
bool ListEmpty()
{
return length == 0;
}
//判断顺序表是否为满
bool ListFull()
{
return length == MaxSize;
}
//删除某个学生数据
bool ListDelete(int,ElemType &e);
//遍历顺序表
void ListTraverse();
//返回顺序表的长度
int ListLength();
//学生数据查询
void GetElem(int, ElemType *);
//修改学生数据
bool UpdateList(ElemType&e, ElemType&e1);
//添加学生数据
bool ListInsert(int, ElemType &);
//对学生数据进行排序
void printlist(int);
//???
bool EqualList(ElemType *, ElemType *);
//???
bool LocateElem(ElemType e, int type);
//???
bool Less_EqualList(ElemType *, ElemType *);
private:
//线性表的数组表示
ElemType elem[MaxListSize];
int length;
int MaxSize;
};
void List::init(List**L,int ms)
{
L = (List)malloc(sizeof(List));
(*L)->length = 0;
(*L)->MaxSize = ms;
}
int List::ListLength()
{
return length;
}
bool List::ListDelete(int mark, ElemType &e)
{
int i, j;
if (ListEmpty())return false;
if (mark > 0)
{
//删除表头元素
e = elem[0];
for (i = 1; i < length; i++)
elem[i - 1] = elem[i];
}
else
{
//删除表尾元素
if (mark < 0)e = elem[length - 1];
else
{//删除值为e的元素
for (i = 0; i < length; i++)
if (strcmp(elem[i].name, e.name) == 0)break;
if (i >= length)return false;
else e = elem[i];
for (j = i + 1; j < length; j++)
elem[j - 1] = elem[j];
}
}
length--;
return true;
}
void List::ListTraverse() } void List::GetElem(int i, ElemType *e) bool List::EqualList(ElemType *e1,ElemType *e2) bool List::LocateElem(ElemType e, int type) } //修改学生数据 bool List::ListInsert(int i, ElemType &e) } //对学生成绩按升序或降序输出 }
{
for (int i = 0; i < length; i++)
{
cout << setw(8) << elem[i].name;
cout << setw(10) << elem[i].stuno;
cout << setw(9) << elem[i].score<}
{
*e = elem[i];
}
{
if (strcmp(e1->name, e2->name))
return false;
if (strcmp(e1->stuno, e2->stuno))
return false;
if (e1->score != e2->score)
return false;
return true;
}
bool List::Less_EqualList(ElemType *e1, ElemType *e2)
{
if (strcmp(e1->name, e2->name) <= 0)return true;
else return false;
}
{
int i;
switch (type)
{
case EQUAL:
for (i = 0; i < length; i++)
{
if (EqualList(&elem[i], &e))
return true;
break;
default:break;
}}
return false;
bool List::UpdateList(ElemType &e, ElemType &e1)
{
for (int i=0;i
{
elem[i] = e1; return true;
}
return false;
}
{
ElemType *p, *q;
if (i<1 || i>length + 1)return false;
q = &elem[i - 1];
for (p = &elem[length - 1]; p >= q; --p)
*(p + 1) = *p;
*q = e;
++length;
return true;
void List::printlist(int mark)
{
int* b = new int[length];
int i, k;
cout << " 姓名 学号 成绩\n";
if (mark != 0) {
for (i = 0; i < length; i++) b[i] = i;
for (i = 0; i < length; i++) {
k = i;
for (int j = i + 1; j < length; j++) {
if (mark == 1 && elem[b[j]].score < elem[b[k]].score) k = j;
if (mark == -1 && elem[b[k]].score < elem[b[j]].score) k = j;
}
if (k != i) { int x = b[i]; b[i] = b[k]; b[k] = x; }
}
for (int i = 0; i < length; i++)
{
cout << setw(8) << elem[b[i]].name;
cout << setw(10) << elem[b[i]].stuno;
cout << setw(9) << elem[b[i]].age;
cout << setw(8) << elem[b[i]].score << endl;
}
}
else {
for (i = 0; i < length; i++)
{
cout << setw(8) << elem[i].name;
cout << setw(10) << elem[i].stuno;
cout << setw(9) << elem[i].age;
cout << setw(8) << elem[i].score << endl;
}
}
}
void main()
{
cout << “linelist1m.cpp运行结果:\n”;
ElemType e, e1, e2, e3, e4, e5, e6;
List *La, *Lb, *Lc;
int k;
cout << “首先调用插入函数.\n”;
La->init(&La, 4);
strcpy(e1.name, “stu1”);
strcpy(e1.stuno, “100001”);
e1.age = 22;
e1.score = 88;
La->ListInsert(1, e1);
strcpy(e2.name, “stu2”);
strcpy(e2.stuno, “100002”);
e2.age = 21;
e2.score = 79;
La->ListInsert(2, e2);
strcpy(e3.name, “stu3”);
strcpy(e3.stuno, “100003”);
e3.age = 19;
e3.score = 87;
La->ListInsert(3, e3);
La->printlist(0);
cout << “表La长:” << La->ListLength() << endl;
cin.get();Lb->init(&Lb, 4);
strcpy(e4.name, "zmofun");
strcpy(e4.stuno, "100001");
e4.age = 20;
e4.score = 94;
Lb->ListInsert(1, e4);
strcpy(e5.name, "bobjin");
strcpy(e5.stuno, "100002");
e5.age = 23;
e5.score = 69;
Lb->ListInsert(2, e5);
strcpy(e6.name, "stu1");
strcpy(e6.stuno, "100001");
e6.age = 22;
e6.score = 88;
Lb->ListInsert(3, e6);
Lb->printlist(0);
cout << "表Lb长:" << Lb->ListLength() << endl;
cin.get();
k = Lc->ListDelete(-1, e6);
if (k == 0) cout << "删除失败!\n";
else cout << "删除成功!\n";
cout << "输出表Lc:\n";
Lc->printlist(0);
cin.get();
cout << "按成绩升序输出表Lc\n";
Lc->printlist(1); cin.get();
cout << "按成绩降序输出表Lc\n";
Lc->printlist(-1); cin.get();