数据结构课程实践1——学生成绩档案管理系统(实验准备)

实验内容

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);
    }

三、相关算法

在对学生成绩进行排序的操作中,采用了四种排序算法。

1、双向冒泡排序

与单向冒泡相似的,双向冒泡排序就是在一趟排序完成之后,同时向两端有序的将元素冒出,使得两端总是保持有序状态,中间无序。
假设有 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;

    }

2、希尔排序

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至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;
    }

3、快速排序

快速排序的核心思想是分治法,分而治之。它的实现方式是每次从序列中选出一个基准值,其他数依次和基准值做比较,比基准值大的放右边,比基准值小的放左边,然后再对左边和右边的两组数分别选出一个基准值,进行同样的比较移动,重复步骤,直到最后都变成单个元素,整个数组就成了有序的序列。

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;
    }

4、堆排序

堆排序是一种树形选择排序方法,它的特点是:在排序的过程中,将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);
        }
    }
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值