1、学生信息录入,信息包括学号、姓名、专业、四门课成绩、总分、名次;
2、系统可对学生信息浏览、增加、删除和修改;
3、按学生成绩确定名次及信息输出,双向冒泡排序、希尔排序、快速排序、堆排序。
4、要求可对学生信息查询,根据学号或姓名进行查找;
信息修改仅可修改四门课成绩;
5、文件存取学生信息。
编程语言:java
开发环境:IDE使用的是idea,jdk版本为1.8
学生成绩档案管理系统可以采用DAO设计模式,DAO全称是(Data Access Object,数据库访问对象),主要功能就是用于进行数据操作的,在程序的标准开发架构中属于数据层的操作。
DAO设计模式主要分为三层:
显示层:主要使用JSP/Servlet进行页面效果的显示
业务层:(Business Object,数据对象)会将多个原子性的DAO操作进行组合,组合成一个完整的业务逻辑。
数据层:(DAO,Data Access Object,数据库访问对象)提供多个原子性的DAO操作,例如:增、删、改、查,都是原子性操作。
首先,明确学生成绩档案管理系统中所涉及到的对象——学生,并创建一个学生类,来存放相关的学生信息。
/**
学生类
*/
public class Student {
/**
定义学生信息,信息包括学号、姓名、专业、四门课成绩、总分、名次
*/
private int number;
private String name;
private String Major;
private double MathScore;
private double EnglishScore;
private double ChineseScore;
private double ArtScore;
private double TotalScore;
private int Rank;
public Student(){
}
其次,创建一个数据类来模拟数据库,初始化学生信息。
/**
* 数据库类
*/
public class Database {
private List<Student> studentList=new ArrayList<>();
/**
* 构造方法中对集合的数据进行初始化
*/
public Database(){
studentList.add(new Student(1001, "Zheng", "软件工程", 95, 89, 86, 75));
studentList.add(new Student(1002, "Jia", "计算机科学与技术", 87, 94, 90, 88));
studentList.add(new Student(1003, "Kun", "软件工程", 91, 88, 85, 79));
studentList.add(new Student(1004, "Xue", "信息安全", 86, 90, 70, 91));
studentList.add(new Student(1005, "Qian", "物联网工程", 97, 81, 90, 72));
studentList.add(new Student(1006, "Wuan", "通信工程", 79, 88, 85, 90));
studentList.add(new Student(1007, "Dian", "计算机科学与技术",89,82, 84, 85));
studentList.add(new Student(1008, "Wang", "物联网工程", 91, 92, 88, 70));
}
然后,创建一个对数据进行操作的类,封装相关的数据访问方法,实现对学生数据进行增、删、改、查、排序的操作。
**
* 封装students相关的数据访问方法
*/
public class StudentDao {
private Database database;
private List<Student> sortList;
public StudentDao(Database database){
this.database=database;
}
最后,创建一个能对学生成绩档案管理系统进行页面效果展示的类,展示整个系统的使用。
/**
* 学生成绩档案管理系统
*/
public class Service {
private StudentDao studentDao;
Scanner scanner=new Scanner(System.in);
public Service(Database database){
studentDao=new StudentDao(database);
}
在对学生成绩进行排序的操作中,采用了四种排序算法。
与单向冒泡相似的,双向冒泡排序就是在一趟排序完成之后,同时向两端有序的将元素冒出,使得两端总是保持有序状态,中间无序。
假设有 N 个待排序元素,则最多只需要 N /2 趟排序,就能使得所有元素变成有序的了。
public List<Student> sortByBubble(){
List<Student> studentList=database.getStudentList();
boolean flag=true;
for(int i=0,j;i<studentList.size()/2&&flag;i++) {
flag = false;
/**
* 正向冒泡排序
*/
for (j = i; j < studentList.size() - 1 - i; j++) {
Student student = new Student();
if (studentList.get(j).getTotalScore() > studentList.get(j + 1).getTotalScore()) {
student = studentList.get(j);
studentList.set(j, studentList.get(j + 1));
studentList.set(j + 1, student);
flag = true;
}
}
/**
* 反向冒泡排序
*/
for (--j; j > i; j--) {
Student student = new Student();
if (studentList.get(j).getTotalScore() < studentList.get(j - 1).getTotalScore()) {
student = studentList.get(j);
studentList.set(j, studentList.get(j - 1));
studentList.set(j - 1, student);
flag = true;
}
}
}
for(int i=0;i<studentList.size();i++)
studentList.get(i).setRank(studentList.size()-i);
return studentList;
}
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
public List<Student> sortByShell(){
List<Student> studentList=database.getStudentList();
int length=studentList.size();
int gap=1;
while(gap<length){
gap=gap*3+1;
}
while(gap>0){
for(int i=gap;i<length;i++){
Student student=studentList.get(i);
int j=i-gap;
//跨区排序
while(j>=0&&studentList.get(j).getTotalScore()> student.getTotalScore()){
studentList.set(j+gap, studentList.get(j));
j-=gap;
}
studentList.set(j+gap, student);
}
gap=gap/3;
}
for(int i=0;i<studentList.size();i++)
studentList.get(i).setRank(studentList.size()-i);
return studentList;
}
快速排序的核心思想是分治法,分而治之。它的实现方式是每次从序列中选出一个基准值,其他数依次和基准值做比较,比基准值大的放右边,比基准值小的放左边,然后再对左边和右边的两组数分别选出一个基准值,进行同样的比较移动,重复步骤,直到最后都变成单个元素,整个数组就成了有序的序列。
public List<Student> sortByQuick(){
List<Student> studentList=database.getStudentList();
sort(studentList,0,studentList.size()-1);
for(int i=0;i<studentList.size();i++)
studentList.get(i).setRank(studentList.size()-i);
return studentList;
}
private void sort(List<Student> studentList,int startIndex,int endIndex){
if(endIndex<=startIndex)
return;
//切分
int midIndex=partition(studentList, startIndex, endIndex);
sort(studentList, startIndex, midIndex-1);
sort(studentList, midIndex+1, endIndex);
}
private int partition(List<Student> studentList,int startIndex,int endIndex){
double mid=studentList.get(startIndex).getTotalScore(); //取基准值
int mark=startIndex;
for(int i=startIndex+1;i<=endIndex;i++){
if(studentList.get(i).getTotalScore()<mid){
//小于基准值 则mark+1,并交换位置。
mark++;
Student student=studentList.get(mark);
studentList.set(mark, studentList.get(i));
studentList.set(i, student);
}
}
//基准值与mark对应元素调换位置
studentList.set(startIndex,studentList.get(mark));
studentList.set(mark, studentList.get(startIndex));
return mark;
}
堆排序是一种树形选择排序方法,它的特点是:在排序的过程中,将array[0,…,n-1]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲节点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(最小)的元素。
public List<Student> sortByHeap(){
List<Student> studentList=database.getStudentList();
int length=studentList.size();
//构建堆
buildHeap(studentList, length);
for(int i=length-1;i>0;i--){
Student student=studentList.get(0);
studentList.set(0, studentList.get(i));
studentList.set(i, student);
length--;
sink(studentList, 0, length);
}
for(int i=0;i<studentList.size();i++)
studentList.get(i).setRank(studentList.size()-i);
return studentList;
}
private void buildHeap(List<Student> studentList,int length){
for(int i=length/2;i>=0;i--){
sink(studentList,i,length);
}
}
private void sink(List<Student> studentList,int index,int length){
int leftchild=2*index+1;//左子节点下标
int rightchild=2*index+2;//右子节点下标
int present=index;
if(leftchild<length&&studentList.get(leftchild).getTotalScore()>studentList.get(present).getTotalScore())
present=leftchild;
if(rightchild<length&&studentList.get(rightchild).getTotalScore()>studentList.get(present).getTotalScore())
present=rightchild;
if(present!=index){
Student student=studentList.get(index);
studentList.set(index, studentList.get(present));
studentList.set(present, student);
}
}
}