一、晨考
题 1:
public class Exam1{
public static void main(String[] args){
//使用循环输出小写的26个英文字母,输出语句System.out.println();
}
}
题 2:
public class Exam2{
public static void main(String[] args){
//使用循环输出平年12个月以及每个月总天数
//1,3,5,7,8,10,12是31天,4,6,9,11是30天,2月是28天
}
}
题 3:
import java.util.Scanner;
public class Exam3{
public static void main(String[] args){
//从键盘输入一个正整数,且必须是3的倍数,否则重新输入。提示输入整数用 input.nextInt();
Scanner input = new Scanner(System.in);
input.close();
}
}
答案:
public class Exam1{
public static void main(String[] args){
//使用循环输出小写的26个英文字母,输出语句System.out.println();
for(char letter='a'; letter<='z'; letter++){
System.out.println(letter);
}
System.out.println("=================");
for(int i=97; i<97+26; i++){
System.out.println((char)i);
}
System.out.println("=================");
for(int i=0; i<26; i++){
System.out.println((char)(i+'a'));
}
}
}
public class Exam2 {
public static void main(String[] args) {
//使用循环输出平年12个月以及每个月总天数
//1,3,5,7,8,10,12是31天,4,6,9,11是30天,2月是28天
/*for(int i=1; i<=12; i++){
if(i==2){
System.out.println(i + "月是28天");
}else if(i==4 || i==6 || i==9 || i==11){
System.out.println(i + "月是30天");
}else{
System.out.println(i + "月是31天");
}
}*/
for (int i = 1; i <= 12; i++) {
switch (i) {
case 2 -> System.out.println(i + "月是28天");
case 4, 6, 9, 11 -> System.out.println(i + "月是30天");
default -> System.out.println(i + "月是31天");
}
}
}
}
import java.util.Scanner;
public class Exam3{
public static void main(String[] args){
//从键盘输入一个正整数,且必须是3的倍数,否则重新输入。提示输入整数用 input.nextInt();
Scanner input = new Scanner(System.in);
/*while(true) {
System.out.print("请输入一个正整数,且必须是3的倍数:");
int num = input.nextInt();
if(num > 0 && num%3==0){
System.out.println("num = " + num);
break;
}else{
System.out.println("输入错误!");
}
}*/
int num;
do{
System.out.print("请输入一个正整数,且必须是3的倍数:");
num = input.nextInt();
if(num<=0 || num%3!=0){
System.out.println("输入错误!");
}
}while(num<=0 || num%3!=0);
System.out.println("num = " + num);
input.close();
}
}
二、复习
1、三种循环结构:for,while,do-while
for 的语法格式:
for(【①循环变量初始化】; 【②循环条件】 ; 【③修改循环变量的迭代表达式】){
④循环体语句;
}
执行过程:①② 成立 ④③② 成立 ④③② 成立 ④③② 不成立结束
while 的语法格式:
while(循环条件){
循环体语句;
}
执行过程:只要循环条件成立,就一直执行循环体语句,直到循环条件不成立为止。
do_while 的语法格式:
do{
循环体语句;
}while(循环条件);
执行过程:只要循环条件成立,就一直执行循环体语句,直到循环条件不成立为止。循环体语句至少执行 1 次。
2、3 个关键字
break | continue | return | |
---|---|---|---|
用在什么结构中 | 循环或 switch-case | 循环 | 方法中 |
作用 | 结束当前循环或 switch-case | 结束本次循环,跳过本次循环剩下的语句,直接进入下一次循环 | 结束当前方法 |
3、学过哪些关键字
8种基本数据类型:byte,short,int,long,float,double,char,boolean
流程控制语句相关:if,else,switch,case,default,for,while,do,break,continue,return
上下文关键字:yield
三、数组
3.1 什么是数组(能分清名词)
数组(array):用于存储一组``相同数据类型
的数据。每一个数组中的数据,一般称为元素(element)
。每一个元素会通过一个编号进行区分,这个编号称为下标(index)
。这组数据的总个数,我们称为数组的长度(length)
。这组数据有一个统一的名称,我们称为数组名。
总结:数组是用来存储和管理一组数据的容器或数据结构。
3.2 数组的特点(掌握)
- 数组的元素是连续存储,即 JVM 会给数组开辟一整块连续的存储空间
- 优点:根据下标访问元素效率很高
- 数组的长度一旦确定,就不能修改
- 缺点:对于元素个数不确定的情况,它是比较麻烦
3.3 数组的声明和初始化(掌握)
3.3.1 数组的使用演示
public class ArrayTest1 {
public static void main(String[] args) {
//例如:存储第1组8个人的成绩
/*int s1 = 89;
int s2 = 85;
int s3 = 100;
int s4 = 96;
int s5 = 75;
int s6 = 53;
int s7 = 60;
int s8 = 78;*/
//求它们的总分,平均分,最高分,最低分,排序
//int[]代表的是数组类型,它是一组数据
int[] scores = {89, 85, 100, 96, 75, 53, 60, 78};
/*System.out.println("第1个同学的成绩:" + scores[0]);
System.out.println("第2个同学的成绩:" + scores[1]);
System.out.println("第3个同学的成绩:" + scores[2]);*/
//数组的遍历
for (int i = 0; i < scores.length; i++) {
System.out.println("第" + (i+1) + "个同学的成绩:" + scores[i]);
}
}
}
3.3.2 数组的声明与静态初始化
//1、数组先声明 并初始化
元素的类型[] 数组名 = {值1,值2, 值3};
//1、数组先声明
元素的类型[] 数组名;
//2、再初始化
数组名 = new 元素的类型[]{值1,值2, 值3};
public class ArrayTest2 {
public static void main(String[] args) {
//1、数组先声明
//元素的类型[] 数组名;
//例如:存储26个字母, char[] letter;
// 例如:存储10件商品的价格, double[] price;
//例如:存储8个同学的成绩: int[] score;
//例如:存储8个同学的姓名: String[] name;
// int[] score = {89,96,85,75};
int[] score;
score = new int[]{89,96,85,75};
//System.out.println(score);//[I@4eec7777
/*
本质上它是score数组对象的类型@hashCode值,
初学者可以直接看成数组对象的首地址
*/
// System.out.println("第1个元素:" + score[0]);
//遍历数组的快捷键:数组名.fori
for (int i = 0; i < score.length; i++) {
System.out.println(score[i]);
}
}
}
3.3.3 数组的遍历
//数组名.fori
for (int i = 0; i < 数组名.length; i++) {
System.out.println(数组名[i]);
}
3.3.4 数组的声明与动态初始化
元素的类型[] 数组名 = new 元素的类型[长度];
此时元素有默认值:
数组的类型 | 元素的类型 | 元素的默认值 |
---|---|---|
byte[] | byte | 0 |
short[] | short | 0 |
int[] | int | 0 |
long[] | long | 0L |
float[] | float | 0.0F |
double[] | double | 0.0 |
char[] | char | \u0000 编码值为 0 的空字符 |
boolean[] | boolean | false |
引用数据类型,例如:String | 例如:String | null |
import java.util.Scanner;
public class ArrayTest3 {
public static void main(String[] args) {
//要存储5个成绩
//元素的类型[] 数组名 = new 元素的类型[长度];
//数组名[下标] 与 数据类型[长度]
//下标的范围是[0, 长度-1]
int[] score = new int[5];
//给元素赋值
/*score[0] = 89;
score[1] = 96;
score[2] = 85;
score[3] = 75;
score[4] = 100;*/
Scanner input = new Scanner(System.in);
for (int i = 0; i < score.length; i++) {
System.out.print("请输入第" + (i+1) +"个同学的成绩:");
score[i] = input.nextInt();
}
System.out.print("他们的成绩如下:");
for (int i = 0; i < score.length; i++) {
System.out.print(score[i] +" ");
}
System.out.println();
input.close();
}
}
3.4 数组的内存分析(理解即可)
3.5 练习题
练习题 1
public class ArrayExercise1 {
public static void main(String[] args) {
//随机产生5个[0,100)的偶数放到数组中 ,并遍历输出
//思路一:确保产生的就是[0,100)的偶数,一共产生5次
/*
Math.random()*50 得到[0,50)的小数
(int)(Math.random()*50) 得到[0,50)的整数,可能是奇数可能是偶数
(int)(Math.random()*50) * 2 得到[0,100)的偶数
*/
int[] nums = new int[5];
/*for (int i = 0; i < nums.length; i++) {
nums[i] = (int)(Math.random()*50) * 2;
System.out.print(nums[i]+" ");
}*/
//思路二:产生的可能是奇数可能是偶数,当产生的是偶数时,放到元素中,产生的是奇数时,抛弃,重新产生,可能产生>5次
/* for (int i = 0; i < nums.length; ) {
int temp = (int)(Math.random()*100);
if(temp % 2 == 0){
nums[i] = temp;
i++;
}
}*/
for (int i = 0; i < nums.length; i++) {
int temp = (int)(Math.random()*100);
if(temp % 2 == 0){
nums[i] = temp;
}else{
i--;
}
}
}
}
练习题 2
import java.util.Scanner;
public class ArrayExercise2 {
/*
(1)用一个数组,保存星期一到星期天的7个英语单词,数组如下:
{"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}
(2)从键盘输入1-7的整数,显示该整数对应的单词
*/
public static void main(String[] args) {
String[] weekName = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
Scanner input = new Scanner(System.in);
int week;
while(true) {
System.out.print("请输入[1,7]的星期值:");
week = input.nextInt();
if (week < 1 || week > 7) {
System.out.println("输入有误!");
}else{
break;
}
}
/*
week=1,输出 weekName[0]
week=2,输出 weekName[1]
...
*/
System.out.println("星期值是" + week + ",对应的单词:" + weekName[week-1]);
input.close();
}
}
练习题 3
public class ArrayExercise3 {
public static void main(String[] args) {
/*
(1)用一个数组存储26个英文字母的小写形式a-z
(2)正序遍历输出小写字母
(3)逆序遍历输出小写字母
*/
// char[] letters = {'a','b','c',....};
char[] letters = new char[26];
/*
letters[0] 存储 'a' 等价于 (char)('a' + 0)
letters[1] 存储 'b' 等价于 (char)('a' + 1)
letters[2] 存储 'c' (char)('a' + 2)
...
letters[i] 存储 (char)('a' + i)
*/
for (int i = 0; i < letters.length; i++) {
letters[i] = (char)('a'+i);
System.out.print(letters[i]);
}
System.out.println();
// System.out.println(letters);
for(int i=letters.length-1; i>=0; i--){
System.out.print(letters[i]);
}
}
}
练习题 4
import java.util.Scanner;
public class ArrayExercise4 {
public static void main(String[] args) {
/*
(1)已知平年12个月每个月的总天数是{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,31},
(2)从键盘输入年,月,日,分别用year,month,day变量接收
(3)计算这一天是这一年的第几天。
(4)提示:闰年的判断标准
- 年份year可以被4整除,但不能被100整除
- 或年份year可以被400整除
*/
int[] totalDaysOfMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Scanner input = new Scanner(System.in);
System.out.print("请输入年 月 日");
int year = input.nextInt();
int month = input.nextInt();
int day = input.nextInt();
//假设输入是合法
/*//单独处理
if (month > 2) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
totalDaysOfMonth[1] = 29;
}
}*/
/*
(1)[1, month-1]满月天数 totalDaysOfMonth[0] ~ totalDaysOfMonth[month-2]
(2)第month月的day天
*/
int days = day; //这么写表示day天已经加到days变量中
for (int i = 0; i < month - 1; i++) {
if(i == 1){//i=1,处理2月份
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
days++;
}
}
days += totalDaysOfMonth[i];
}
System.out.println(year + "年" + month + "月" + day + "日是这一年的第" + days + "天");
input.close();
}
}
3.6 1 个数组还是 2 个数组的问题(能识别)
情况 1
public class OneOrTwoArrayTest {
public static void main(String[] args) {
int[] a = {1,2,3};
int[] b = a; //配了一把钥匙,与a开同一个柜子
b[1] = 100;
/*
思考:这里有几个数组?有几个柜子?
这里有2个数组变量,但是它们指向同一个数组
*/
System.out.println("a数组的元素:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
//1 100 3
System.out.println();
System.out.println("b数组的元素:");
for (int i = 0; i < b.length; i++) {
System.out.print(b[i]+" ");
}
//1 100 3
}
}
情况 2
public class OneOrTwoArrayTest2 {
public static void main(String[] args) {
int[] a = {1,2,3};
int[] b = new int[a.length];
b[1] = 100;
/*
思考:这里有几个数组?有几个柜子?
这里有2个数组变量,也有2个数组,它们指向不同一个数组
*/
System.out.println("a数组的元素:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
//1 2 3
System.out.println();
System.out.println("b数组的元素:");
for (int i = 0; i < b.length; i++) {
System.out.print(b[i]+" ");
}
//0 100 0
}
}
情况 3
public class OneOrTwoArrayTest3 {
public static void main(String[] args) {
int[] a = {1,2,3};
a = new int[a.length];
a[1] = 100;
/*
思考:这里有几个数组?有几个柜子?
这里有2个数组变量,也有2个数组,它们指向不同一个数组
*/
System.out.println("a数组的元素:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
//0 100 0
}
}
3.7 数组的基础算法
3.7.1 什么是算法
算法:解决问题的步骤。例如:在数组中找最大值,它的固定套路就是一个算法。
今天咱们学习:
- 统计数组元素满足 xx 条件的个数
- 统计数组元素的总和、平均值
- 在数组中找最大值、最小值
- 在数组中找最大/小值及其下标
- 数组元素的反转,例如:1,2,3,4,5 变为 5,4,3,2,1
- 数组元素查找,即某个值在不在数组中
- 数组元素的排序
3.7.2 算法一:统计数组元素满足 xx 条件的个数(掌握)
需求:随机产生 10 个[0,100)的整数放到数组中,统计其中偶数的个数、3 的倍数、5 的倍数的个数。
public class ArrayArithmeticTest1 {
public static void main(String[] args) {
//需求:随机产生10个[0,100)的整数放到数组中,统计其中偶数的个数、3的倍数、5的倍数的个数。
//(1)定义一个数组,长度为10,元素类型是int
int[] arr = new int[10];
//(2)随机产生10个[0,100]的整数放到数组中,并且输出
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100);
System.out.print(arr[i]+" ");
}
System.out.println();
//(3)统计其中偶数的个数、3的倍数、5的倍数的个数
int evenCount = 0;
int threeCount = 0;
int fiveCount = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i] % 2 == 0){
evenCount++;
}
if(arr[i] % 3 == 0){
threeCount++;
}
if(arr[i] % 5 == 0){
fiveCount++;
}
}
System.out.println("偶数的个数:" + evenCount);
System.out.println("3的倍数的个数:" + threeCount);
System.out.println("5的倍数的个数:" + fiveCount);
}
}
public class ArrayArithmeticTest1_2 {
public static void main(String[] args) {
//需求:随机产生10个[0,100)的整数放到数组中,统计其中偶数的个数、3的倍数、5的倍数的个数。
//(1)定义一个数组,长度为10,元素类型是int
int[] arr = new int[10];
//(2)随机产生10个[0,100]的整数放到数组中,并且输出
//(3)统计其中偶数的个数、3的倍数、5的倍数的个数
int evenCount = 0;
int threeCount = 0;
int fiveCount = 0;
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100);
System.out.print(arr[i]+" ");
if(arr[i] % 2 == 0){
evenCount++;
}
if(arr[i] % 3 == 0){
threeCount++;
}
if(arr[i] % 5 == 0){
fiveCount++;
}
}
System.out.println();
System.out.println("偶数的个数:" + evenCount);
System.out.println("3的倍数的个数:" + threeCount);
System.out.println("5的倍数的个数:" + fiveCount);
}
}
3.7.3 算法二:统计元素的总和与平均值(掌握)
需求:从键盘输入你们组的人数,以及每一个人的成绩,然后输出你们组的总分,平均分。
import java.util.Scanner;
public class ArrayArithmetic2 {
public static void main(String[] args) {
//需求:从键盘输入你们组的人数,以及每一个人的成绩,成绩存到数组中,然后输出你们组的总分,平均分。
Scanner input = new Scanner(System.in);
//(1)输入人数
int count;
while(true) {
System.out.print("请输入本组的人数:");
count = input.nextInt();
if(count>0){
break;
}else if(count>Integer.MAX_VALUE){
System.out.println("输入错误,人数太多了");
}else{
System.out.println("输入错误,人数应该为正数!");
}
}
//(2)定义数组,长度为count,元素类型可以是int或double
int[] score = new int[count];
//(3)输入成绩
for (int i = 0; i < score.length; i++) {
System.out.print("请输入第" +(i+1) +"个同学的成绩:");
score[i] = input.nextInt();//成绩其实也有有效性的判断,这里没写
}
//(4)统计总分和平均分
int sum = 0;
System.out.println("大家的成绩如下:");
for (int i = 0; i < score.length; i++) {
System.out.print(score[i]+" ");
sum += score[i];
}
System.out.println();
System.out.println("总分:" + sum);
System.out.println("平均分:" + (double)sum/count);
input.close();
}
}
3.7.4 算法三:找最大值、最小值(掌握)
需求:随机产生 10 个[0,100)的整数放到数组中,找出最大值和最小值
public class ArrayArithmetic3 {
public static void main(String[] args) {
//需求:随机产生10个[0,100)的整数放到数组中,找出最大值和最小值
//(1)定义长度为10的数组
int[] arr = new int[10];
//(2)随机产生10个[0,100)的整数放到数组中
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100);
System.out.print(arr[i] +" ");
}
System.out.println();
//(3)找出最大值和最小值
//擂台赛
int max = arr[0];//第一个人先上擂台
int min = arr[0];
for(int i=1; i<arr.length; i++){
if(arr[i] > max){
max = arr[i];
}
if(arr[i] < min){
min = arr[i];
}
}
System.out.println("max = " + max);
System.out.println("min = " + min);
}
}
3.7.5 算法四:找最值及其下标(有基础的尽量掌握)
情况一:元素不重复
public class ArrayArithmetic4 {
public static void main(String[] args) {
int[] arr = {8, 9, 5, 6, 4};
//找出最大值及其下标?
int max = arr[0];//存储元素
int index = 0;//存储下标
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
index = i;
}
}
System.out.println("最大值:" + max);
System.out.println("最大值的下标:[" + index +"]");
}
}
public class ArrayArithmetic4_2 {
public static void main(String[] args) {
int[] arr = {8, 9, 5, 6, 4};
//找出最大值及其下标?
int index = 0;//存储下标
for (int i = 1; i < arr.length; i++) {
if(arr[i] > arr[index]){
arr[index] = arr[i];
index = i;
}
}
System.out.println("最大值:" + arr[index]);
System.out.println("最大值的下标:[" + index +"]");
}
}
情况二:元素有重复
public class ArrayArithmetic5 {
public static void main(String[] args) {
int[] arr = {8, 9, 5, 9, 4};
//找出最大值及其下标?
int max = arr[0];//存储元素
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
}
}
System.out.println("最大值:" + max);
System.out.print("最大值的下标:");
for(int i=0; i<arr.length; i++){
if(arr[i] == max){
System.out.print("[" + i+"] ");
}
}
System.out.println();
}
}
public class ArrayArithmetic5_2 {
public static void main(String[] args) {
int[] arr = {9, 9, 5, 9, 4};
//找出最大值及其下标?
int max = arr[0];//存储元素
String index = "0";
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
index = i +"";
}else if(arr[i] == max){
index += "," + i;
}
}
System.out.println("最大值:" + max);
System.out.println("最大值的下标:" + index);
}
}
3.7.6 算法五:元素反转(掌握)
public class ArrayArithmetic6 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
//思路一:找一个同样大小的数组,按逆序存放元素(不够好)
int[] nums = new int[arr.length];
for (int i = 0; i < nums.length; i++) {
nums[i] = arr[arr.length-1-i];
}
//查看两个数组的情况
System.out.print("arr数组:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
System.out.print("nums数组:");
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i]+" ");
}
System.out.println();
System.out.println("==========================");
//让arr指向nums数组,抛弃原来的数组
arr = nums;
//查看两个数组的情况
System.out.print("arr数组:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
System.out.print("nums数组:");
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i]+" ");
}
System.out.println();
}
}
public class ArrayArithmetic7 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
//思路二:首尾对应位置交换
/*for(int left=0,right=arr.length-1; left<right; left++,right--){
//arr[left] 与 arr[right] 交换
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}*/
for(int i=0; i<arr.length/2; i++){
//arr[i] 与 arr[arr.length-1-i]
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i]= temp;
}
//查看两个数组的情况
System.out.print("arr数组:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
3.7.7 算法六:数组元素的查找
情况一:顺序查找法(掌握)
import java.util.Scanner;
public class ArrayArithmetic8 {
public static void main(String[] args) {
/*
需求:随机产生10个[0,100)的整数,然后从键盘输入1个整数,看它在不在这个数组中
*/
//(1)定义长度为10的数组
int[] arr = new int[10];
//(2)随机产生10个[0,100)的整数放到数组中,并且显示元素
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100);
System.out.print(arr[i]+" ");
}
System.out.println();
//(3)从键盘输入1个整数
Scanner input = new Scanner(System.in);
System.out.print("请输入一个整数:");
int target = input.nextInt();
//(4)遍历数组,查找这个整数在不在数组中
boolean flag = false;//false没找到
for (int i = 0; i < arr.length; i++) {
if(arr[i] == target){
flag = true;
break;
}
}
if(flag){
System.out.println("找到了");
}else{
System.out.println("没找到");
}
input.close();
}
}
import java.util.Scanner;
public class ArrayArithmetic9 {
public static void main(String[] args) {
/*
需求:随机产生10个[0,100)的整数,然后从键盘输入1个整数,看它在不在这个数组中
*/
//(1)定义长度为10的数组
int[] arr = new int[10];
//(2)随机产生10个[0,100)的整数放到数组中,并且显示元素
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100);
System.out.print(arr[i]+" ");
}
System.out.println();
//(3)从键盘输入1个整数
Scanner input = new Scanner(System.in);
System.out.print("请输入一个整数:");
int target = input.nextInt();
//(4)遍历数组,查找这个整数在不在数组中
int index = -1;//正常下标不会是-1
for (int i = 0; i < arr.length; i++) {
if(arr[i] == target){
index = i;
break;
}
}
if(index!=-1){
System.out.println("找到了,下标是" + index);
}else{
System.out.println("没找到");
}
input.close();
}
}
情况二:二分查找(预留)
3.7.8 算法七:排序
方式一:冒泡排序(掌握)
冒泡排序(Bubble Sort)是一种简单的排序算法,其核心思想是:
- 重复遍历数组:从头开始依次比较相邻的两个元素。
- 交换位置:如果前一个元素大于后一个元素,则交换它们的位置。
- 每轮遍历将最大值“冒泡”到末尾:经过一轮遍历后,最大的元素会移动到最后。
- 逐步缩小范围:对剩余未排序部分重复上述过程,直到整个数组有序。
硬写版:(为了推导过程)
public class ArrayArithmetic10 {
public static void main(String[] args) {
int[] arr = {6, 9, 2, 9, 1};
//第1轮:比较4次 j=0,1,2,3
/*
arr[0]与arr[1]
arr[1]与arr[2]
arr[2]与arr[3]
arr[3]与arr[4]
arr[j] 与 arr[j+1]
*/
for(int j=0; j<4; j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
//第二轮:比较3次, j=0,1,2
/*
arr[0]与arr[1]
arr[1]与arr[2]
arr[2]与arr[3]
arr[j] 与 arr[j+1]
*/
for(int j=0; j<3; j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
//第三轮:比较2次, j=0,1
/*
arr[0]与arr[1]
arr[1]与arr[2]
arr[j] 与 arr[j+1]
*/
for(int j=0; j<2; j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
//第四轮:比较1次, j=0
/*
arr[0]与arr[1]
arr[j] 与 arr[j+1]
*/
for(int j=0; j<1; j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
//最终结果
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
基础版:
public class ArrayArithmetic10_2 {
public static void main(String[] args) {
int[] arr = {6, 9, 2, 9, 1};
/*
5个元素,需要4轮,i=1,2,3,4 i<5, i<arr.length
i=1, 第1轮: j<4
i=2, 第2轮: j<3
i=3, 第3轮: j<2
i=4, 第4轮: j<1
j<arr.length-i
*/
for(int i=1; i<arr.length; i++) {
for (int j = 0; j<arr.length-i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
//最终结果
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
public class ArrayArithmetic10_3 {
public static void main(String[] args) {
int[] arr = {6, 9, 2, 9, 1};
/*
5个元素,需要4轮,i=0,1,2,3 i<4, i<arr.length-1
i=0, 第1轮: j<4
i=1, 第2轮: j<3
i=2, 第3轮: j<2
i=3, 第4轮: j<1
j<arr.length-i
*/
for(int i=0; i<arr.length-1; i++) {
for (int j = 0; j<arr.length-i-1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
//最终结果
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
思考题:有基础的同学思考,冒泡排序怎么优化,即在数组元素基本有序的情况下,提前结束冒泡排序,不需要经过 n-1 轮。
方式二:选择排序(拓展)
直接选择排序(Straight Selection Sort)是一种简单直观的排序算法,其核心思想是:
- 从数组中选择最值(最大或最小):每次从未排序部分选取最小(或最大)的元素。
- 与未排序部分的第一个元素交换位置:将该最值放到已排序序列的末尾。
- 逐步缩小范围:重复上述过程,直到所有元素有序。
以下代码采用“边比较边交换”的方式,而不是“先找最小值再交换”,虽然效率较低,但是对于初学者相对好理解。
硬写版(为了推导过程)
public class ArrayArithmetic11 {
public static void main(String[] args) {
int[] arr = {6, 9, 2, 9, 1};
//第1轮:所有元素 arr[1],arr[2],arr[3],arr[4] 都与arr[0]比较
for(int j=1; j<arr.length; j++){
if(arr[j]<arr[0]){
int temp = arr[0];
arr[0] = arr[j];
arr[j] = temp;
}
}
//第2轮:所有元素 arr[2],arr[3],arr[4] 都与arr[1]比较 , arr[0]不参与
for(int j=2; j<arr.length; j++){
if(arr[j]<arr[1]){
int temp = arr[1];
arr[1] = arr[j];
arr[j] = temp;
}
}
//第3轮:所有元素 arr[3],arr[4] 都与arr[2]比较 , arr[0],arr[1]不参与
for(int j=3; j<arr.length; j++){
if(arr[j]<arr[2]){
int temp = arr[2];
arr[2] = arr[j];
arr[j] = temp;
}
}
//第4轮:所有元素 arr[4] 都与arr[3]比较 , arr[0],arr[1],arr[2]不参与
for(int j=4; j<arr.length; j++){
if(arr[j]<arr[3]){
int temp = arr[3];
arr[3] = arr[j];
arr[j] = temp;
}
}
System.out.println("排序结果:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
基础版:
public class ArrayArithmetic11_2 {
public static void main(String[] args) {
int[] arr = {6, 9, 2, 9, 1};
//第1轮:所有元素 arr[1],arr[2],arr[3],arr[4] 都与arr[0]比较
//第2轮:所有元素 arr[2],arr[3],arr[4] 都与arr[1]比较 , arr[0]不参与
//第3轮:所有元素 arr[3],arr[4] 都与arr[2]比较 , arr[0],arr[1]不参与
//第4轮:所有元素 arr[4] 都与arr[3]比较 , arr[0],arr[1],arr[2]不参与
/*
i=1,2,3,4 一共四轮
第1轮i=1, j=1; j<arr.length; 所有元素与arr[0]
第2轮i=2, j=2; j<arr.length; 所有元素与arr[1]
第3轮i=3, j=3; j<arr.length; 所有元素与arr[2]
第4轮i=4, j=4; j<arr.length; 所有元素与arr[3]
j=i; j<arr.length; 所有元素与arr[i-1]
*/
for(int i=1; i<arr.length; i++) {
for (int j = i; j < arr.length; j++) {
if (arr[j] < arr[i-1]) {
int temp = arr[i-1];
arr[i-1] = arr[j];
arr[j] = temp;
}
}
}
System.out.println("排序结果:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
思考题:有基础的同学思考,直接选择怎么优化,思路,把后续未排序中最小值找出来,与预定位置的元素交换。