基本任务:
设计合理的数据结构,实现学生信息管理系统。要求有:
1.系统以菜单的方式工作;
2.有以下信息更新功能;
(1)追加学生信息。输入相应的数据生成节点,插入到相应的链表里;
(2)删除学生信息。输入学生的编号,自动将对应学生的信息删除;
(3)更改学生信息。修改学生的各种资料信息。
(4)学生信息表能够以文件形式进行存取。
3.排序功能,实现按照某种属性,升/降序的排序功能;
4.查询功能;查询所保存的所有学生的信息,并打印输出至屏幕。
5.每个学生的信息生成一个节点,每个节点包括域: 学号、姓名、性别、籍贯、政治面貌、所在学院、专业、身份证号码、本人联系方式、住址、邮编。
并且要进行管理的学生信息是大量的。
总体设计:
程序运行时首先显示主菜单,有9个选项,用户进行选择,输入数字进入对应功能,功能实现完会结束或者返回主菜单界面,进入9时程序结束运行。
数据准备:
1.生成大量学生信息
采用java调用Math类的Random方法获取随机数,将生成的数据存入txt文本文件中,总共获得106558条数据。将该文本文件存入C盘根目录下,并命名为read.txt。
package test;
import java.util.Random;
public class test{
public static void main(String[] args) {
// WebDriver webDriver = new ChromeDriver();
// // 新建Actions类,声明一个动作
// Actions action = new Actions(webDriver);
// Login.login(webDriver, action);
// String[] names = { "李", "王", "张", "刘", "陈", "杨", "赵"};
// String[] lastNames = {"三", "四" };
// String[] phones = { "11","12","13", "14","15", "21", "22", "23", "31"
// , "32", "33", "34", "35", "36", "37", "41", "42", "43", "44", "45"
// , "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71"};
// String[] phones2 = {"0","1","2","3","4","5","6","7","8","9","X"};
//String[] scode = {"100000","201100","137400","061000","112700","116000","214000","237000",
//"261000","266000","276800","721000","230000","433000","431600","441300","472000"
//,"528400","561000","643000","751600","054000","300480","012600","030000","044000"
//,"225000","256600"};
String[] splaces = {"上海市金山县","呼和浩特市包头市","山西省太原市","陕西省咸阳市","江苏省连云港市","山东省青岛市","河南省郑州市","江苏省扬州市","安徽省六安市","浙江省杭州市","江西省南昌市","江西省九江市","湖南省株洲市","广东省广州市","广西省百色市"};
int random = getRandom(100000000, 999999999);
for (int i = 0; i < 5459; i++) {
// String name = names[(int) (Math.random() * names.length)]
// + lastNames[(int) (Math.random() * 4)];
// String phone = phones[(int) (Math.random() * phones.length)]
// + (int) (Math.random() * 10) + random
// + (int) (Math.random() * 10) + (int) (Math.random() * 10)
// + (int) (Math.random() * 10)+ (int) (Math.random() * 10)
// + (int) (Math.random() * 10)+phones2[(int)(Math.random() * phones2.length)];
//System.out.println(phone);
//String scodea = scode[(int) (Math.random() * scode.length)];
//System.out.println(scodea);
String splace = splaces[(int) (Math.random() * splaces.length)];
System.out.println(splace);
}
}
public static int getRandom(int min, int max) {
int randomNum = 0;
try {
Thread.sleep(1000);
Random random = new Random();
// 获取随机的数,范围值包小包大
randomNum = random.nextInt(max) % (max - min + 1) + min;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("获取随机整数,发生异常:" + e.getMessage());
}
return randomNum;
}
}
2.测试从文本导入数据
执行菜单选项1,导入数据,输入C:\\read.txt 进行数据导入。第一次导入时失败,并出现乱码,想到是因为文件中存在中文导致的问题。经过查阅资料,发现解决这个问题的方法是将编译器的命令行与文本文件的编码方式修改成一致。在codeblocks菜单中查看编译器的编码方式,打开Setting/Editor/Encoding Setting 中可以看见,默认是windows-936(也就是gbk格式),而该文本文件为utf-8格式,因此修改txt文件编码格式为ANSI,使二者达到一致。保存后再次导入便成功了,如图2所示。
在测试过程中也遇到过信息全部导入成功,但是最后一条记录显示插入失败的情况,用查询对最后一条记录进行查找,发现能够查找到最后一条记录,这种情况的出现是因为文本文档中最后一行多了一行换行符。此时将最后一个字符后边的空格删掉就可以正常显示了。
3.文件导出测试
测试将操作后的树中的全部数据导出。选择菜单8选项,输入路径为C:\\write.txt,将其导出到该位置,导出结果正常。
1.学生信息删除函数:
node* delete_student(node* T, int sno),功能是根据用户输入的学号,删除这个学号对应的学生信息。入口参数是根节点T以及要删除的学生学号sno,出口参数是返回的T。
具体的实现思路是:首先判断树是否为空,树为空直接返回,并提示删除失败。
树不为空时,进行删除操作。如果找到了要删除的节点,则进行删除的具体操作,如果要删除的学号比找到的这个节点的学号数值小,则继续递归地往它的左子树去找;如果要删除的学号比找到的这个节点的学号数值大,则继续递归地往它的右子树去找。删除的具体操作是:找到的节点分为三种情况:一是为叶子节点,此时直接删除即可;二是只有一棵右子树,用tmp来记录它的右子树中的最左边的节点即右子树中的最小值,将右子树中的最小值赋值到要删除的节点上,然后递归地删除掉重复出来的这个节点,将右子树的数据更新进来;三是有左子树,用tmp来记录它的左子树当中的最右边的节点即左子树中的最大值,将左子树中的最大值赋值到要删除的节点上,覆盖这个节点,递归地删除掉重复出来的这个节点,将左子树的数据更新进来。删除后要判断是否出现不平衡,删除左子树上节点相当于在右子树上插入了一个新节点,删除右子树同理。
因此需要调用的函数有:函数递归的调用自身,以完成删除;调用getHeight()函数,通过比较左右子树的高度来判断是否因为删除而导致二叉树不平衡。并通过调用LLAdujust(T)、LRAdujust(T)、RLAdujust(T)、RRAdujust(T)进行相应的调整。
2.学生信息导入函数
node* import(node* T),功能是将学生信息批量地从文本文件导入到二叉树中。入口参数是根节点T,出口参数是返回的T。其中在逐行读取插入的时候调用了插入函数insert_student(T,tempdata)。
3.学生信息导出函数
void export_student(node* T),功能是将二叉树中的数据写入文本文件中并保存。入口参数是根节点T,无返回值。没有调用其他功能函数。
程序使用方法说明:
若选择序号1,进入后请按提示输入要导入的文件所在的路径。此时应注意文件应该是按ANSI编码的txt文件,并且输入的路径中不要有空格,路径的输入方式要进行转义,如:
C:\\test\\test.txt。如果输入的路径有误,会提示错误并终止程序。Txt文件的最后一行不要有多余的换行符,否则会多显示一条换行符的插入失败信息。
若选择序号2,按提示依次输入学号 姓名 性别 籍贯 政治面貌 所在学院 专业 身份证号码 本人联系方式 住址 邮编(以空格或换行符间隔),按回车完成插入,会返回到主菜单界面。输入的学号不允许重复,否则会提示输入失败。
若选择序号3,按提示输入要删除的学生信息对应的学号。按回车会完成删除并返回主菜单界面,此时会检查输入的学号是否合法。如果要删除的学生信息不存在,会提示删除失败。
若选择序号4,按提示输入想要查询的条件。例如按学号查询,则学号输入要查询的学号,其它均输入#;按姓名查询则学号输入0,姓名输入要查询的姓名,其它均输入#。
若选择序号5,按提示输入想要更新的学生的学号,并依次输入更新后的学生信息,按回车后显示更新是否成功并返回主菜单。
若选择序号6,将跳到选择排序方式的菜单界面,可以选择按学号、姓名或者籍贯排序。以按学号排序为例,输入11并回车可以跳到排序方式,升序还是降序,以及排序算法,还可以选择返回,输入返回序号25将返回到上一级菜单。以选择降序选择排序算法为例,输入24,将显示排序结果及运行时间,并自动返回了上一级菜单。
若选择序号7,将按中序遍历打印所有学生信息,显示在屏幕并自动返回主菜单。
若选择序号8,按提示输入要导出的文件路径即可,路径的要求同导入相同。如果为空树,会提示树空,并返回主菜单。
若选择序号9,将显示感谢使用并退出整个程序。
获取完整工程在资源下载StudentMangeSystem.zip即可。