jscfa-java作业 20251022
作业1
原题
冒泡排序(自小到大,即每一趟排序从数组最后两个元素开始,把小值往前挪,直到最前面两个元素,即可完成整个数组最小元素冒泡到最前面);
代码
//反向冒泡算法
//引入随机函数
import java.util.Random;
public class Homework_20251022_1_HZW {
//主方法
public static void main(String[] args){
//创建随机数组
Random rand = new Random();
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(100) + 1;
}
//展示原始数组
System.out.print("原始数组:\t");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
//反向冒泡算法
for (int i = 0; i < arr.length; i++) {
for (int j = arr.length - 1 ; j > i; j--) {
if (arr[j] < arr[j - 1]) {
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
}
System.out.print("第"+(i+1)+"次排序:\t");
for (int k = 0; k < arr.length; k++) {
System.out.print(arr[k] + "\t");
}
System.out.println();
}
//展示排序后结果
System.out.print("结果:\t");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
运行结果
"C:\Program Files\Java\jdk-21\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2025.2.2\lib\idea_rt.jar=61131" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\workspace\jscfa-java\runtimeSpace\out\production\runtimeSpace Neko
原始数组: 80 14 24 48 4 47 68 46 10 88
第1次排序: 4 80 14 24 48 10 47 68 46 88
第2次排序: 4 10 80 14 24 48 46 47 68 88
第3次排序: 4 10 14 80 24 46 48 47 68 88
第4次排序: 4 10 14 24 80 46 47 48 68 88
第5次排序: 4 10 14 24 46 80 47 48 68 88
第6次排序: 4 10 14 24 46 47 80 48 68 88
第7次排序: 4 10 14 24 46 47 48 80 68 88
第8次排序: 4 10 14 24 46 47 48 68 80 88
第9次排序: 4 10 14 24 46 47 48 68 80 88
第10次排序: 4 10 14 24 46 47 48 68 80 88
结果: 4 10 14 24 46 47 48 68 80 88
进程已结束,退出代码为 0

作业2
原题
已知某门课10个人的成绩,求最高分、最低分,平均分,以及第一名到最后一名的排序(从高分到低分排序)
代码
import java.util.Random;
public class Homework_20251022_2_HZW {
public static void main(String[] args) {
//创建分数数组
Random rand = new Random();
int[] arr = new int[10];
//原始分数
System.out.print("原始分数:\t");
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(100) + 1;
System.out.print(arr[i]+"\t");
}
System.out.println();
//处理最值分数
int tempMax = arr[0];
int tempMin = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > tempMax) {
tempMax = arr[i];
}
if (arr[i] < tempMin) {
tempMin = arr[i];
}
}
System.out.println("最高分:\t"+ tempMax);
System.out.println("最低分:\t"+ tempMin);
//排序
for (int i = 0; i < arr.length - 1 ; i++) {
for (int j = 0 ; j < arr.length - 1 - i; j++) {
if (arr[j] < arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.print("排序结果:\t");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
}
}
运行结果
"C:\Program Files\Java\jdk-21\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2025.2.2\lib\idea_rt.jar=50483" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\workspace\jscfa-java\jscfa\out\production\jscfa Homework_20251022_2_HZW
原始分数: 9 25 20 94 4 57 62 23 51 49
最高分: 94
最低分: 4
排序结果: 94 62 57 51 49 25 23 20 9 4
进程已结束,退出代码为 0

说明
本题中,要求排序,即可以先排序,再直接输出最高分(也就是数组首位arr[0])最低分(也就是数组末位arr[arr.length-1])
如果我们按照如上思路处理,那么代码应该是如下:
import java.util.Random;
public class Homework_20251022_3_HZW {
public static void main(String[] args) {
//创建分数数组
Random rand = new Random();
int[] arr = new int[10];
//原始分数
System.out.print("原始分数:\t");
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(100) + 1;
System.out.print(arr[i]+"\t");
}
System.out.println();
//排序
for (int i = 0; i < arr.length - 1 ; i++) {
for (int j = 0 ; j < arr.length - 1 - i; j++) {
if (arr[j] < arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
//输出
System.out.println("最高分:\t" + arr[0]);
System.out.println("最低分:\t" + arr[arr.length - 1]);
System.out.print("排序结果:\t");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
}
}
订正
教师评语
此排序程序还可以优化,单趟排序中倘若不需要交换,中止整个排序过程
修改
原始的冒泡排序是这样的:
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
这种情况下,无论原始数组排列如何,外圈循环代码均会执行arr.length - 1次。
我们可以举例如下:
import java.util.Random;
public class Homework_20251022_Correction_1_HZW {
public static void main(String[] args) {
Random rand = new Random();
int[] arr = new int[10];
int loopCount = 0;
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(100) + 1;
}
for (int i = 0; i < arr.length - 1 ; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
loopCount = loopCount + 1;
}
System.out.println(loopCount);
}
}
运行结果
9
但是如果,我们的数组在某次循环已经完成排列,即某种机缘巧合下已经完成按序排列,那再这种巧合之后,代码实际上没有作用。
所以,我们在外圈循环中引入一个变量来判断是否在当前循环(内圈循环)是否执行了交换,如果不内圈不执行交换,则表明整个数组都完成了排序。局部代码如下:
for (int i = 0; i < arr.length - 1; i++) {
boolean breakTheLoop = false;
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
breakTheLoop = true;
}
}
if (breakTheLoop == false) {
break;
}
}
如上代码中,我们新增了一个布尔变量breakTheLoop,如果这个值为false(初始值),则表示这次的循环内圈未交换任何排序,那么就说明整个数组都完成了交换。
我们将如上修改的代码放到实际环境运行一下,并执行冒泡排序5次来判断是否有效:
import java.util.Random;
public class Homework_20251022_Correction_1_HZW {
public static void main(String[] args) {
Random rand = new Random();
for (int k = 0; k < 5; k++) {
int[] arr = new int[10];
int loopCount = 0;
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(100) + 1;
}
for (int i = 0; i < arr.length - 1 ; i++) {
boolean breakTheLoop = false;
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
breakTheLoop = true;
}
}
if (breakTheLoop == false) {
break;
}
loopCount = loopCount + 1;
}
System.out.println(loopCount);
}
}
}
运行结果
6
4
6
7
6
这说明在这种情况下是有效减少了循环的次数,提高了运行效率。
需要说明的是,这种修改方案仍然具有冒泡排序的O(n²)最坏时间复杂度。