排序算法和二维数组
1.增强型for循环,也称为foreach循环
(1)格式
for(数组元素数据类型 临时变量 :数组名) {
访问临时变量;
}
(2)作用:对数组的访问是只读的,常用于数组的遍历。
(3)使用下标时用for循环,不使用下标用增强型for循环
2.取子数组
(1)取子数组
public static void main(String[] args) {
int[] arr = new int[8];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 20);
}
// 遍历
for (int tmp : arr) {
System.out.print(tmp + " ");
}
System.out.println();
// 取子数组, 取所有奇数
// 1) 创建新数组, 容量足够大, 和老数组一样
int[] newArr = new int[arr.length];
// 2) 声明计数器, 初值为0, 它是最重要,最核心的, 因为有2个功能
// 计数, 新数组中插入元素的下标的控制.
int count = 0;
// 3) 遍历老数组
for (int i = 0; i < arr.length; i++) {
// 4) 如果找到满足条件的元素
if (arr[i] % 2 != 0) {
// 5) 把此元素插入到新数组 新数组插入时的下标由计数器的当前值控制
newArr[count] = arr[i];
// 7) 调整计数器
count++;
}
}
// 8) 创建最终数组, 长度是计数器
int[] finalArr = new int[count];
// 9) 依次把新数组中的所有有效元素复制到最终数组中
for (int i = 0; i < count; i++) {
finalArr[i] = newArr[i];
}
// 遍历最终数组
for (int tmp : finalArr) {
System.out.print(tmp + " ");
}
System.out.println();
}
(2)取子数组对象
public static void main(String[] args) {
// 创建引用数组, id是从1-10, 年级随机的[1-6], 分数是随机的[0~100]
Student[] stuArr = new Student[5];
for (int i = 0; i < stuArr.length; i++) {
int id = i + 1;
String name = "某同学";
int grade = (int) (Math.random() * 6 + 1);
double score = (int) (Math.random() * 101);
stuArr[i] = new Student(id, name, grade, score);
}
// 遍历数组, 也可以使用增强for
for (Student tmp : stuArr) {
System.out.println(tmp.say());
}
System.out.println("********************************************");
// 取子数组, 取3年级同学
// 1) 创建新数组, 容量足够大, 和老数组一样
Student[] newArr = new Student[stuArr.length]; // 新数组中有空洞, 但是是在所有有效元素之后的. 称为结构良好数组
// 2) 声明计数器, 初值为0, 它是最重要,最核心的, 因为有2个功能
// 计数, 新数组中插入元素的下标的控制.
int count = 0;
// 3) 遍历老数组
for (int i = 0; i < stuArr.length; i++) {
// 4) 如果找到满足条件的元素
if (stuArr[i].getGrade() == 3) {
// 5) 把此元素插入到新数组 新数组插入时的下标由计数器的当前值控制
newArr[count] = stuArr[i];
// 7) 调整计数器
count++;
}
}
// 8) 创建最终数组, 长度是计数器
Student[] finalArr = new Student[count]; // 所有元素都是有效的, 没有空洞, 称为完美数组
// 9) 依次把新数组中的所有有效元素复制到最终数组中
for (int i = 0; i < count; i++) {
finalArr[i] = newArr[i];
}
// 遍历最终数组
for (Student tmp : finalArr) {
System.out.println(tmp.say());
}
}
3.冒泡排序
(1)外循环 —> 控制趟数
(2)内循环 —> 控制每趟的比较次数
(3)排序数组
public static void main(String[] args) {
int[] arr = new int[8];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 20);
}
// 遍历
for (int tmp : arr) {
System.out.print(tmp + " ");
}
System.out.println();
//0 1 2 3 4 5 6 7
//6 7 1 10 9 12 3 11
// 排序
for (int j = 0; j < arr.length - 1; j++) { // 控制趟数
for (int i = 0; i < arr.length - 1 - j; i++) { // 控制每趟的比较次数
if (arr[i] > arr[i + 1]) {
int tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
}
}
}
// 遍历
for (int tmp : arr) {
System.out.print(tmp + " ");
}
System.out.println();
}
(4)排序数组对象
public static void main(String[] args) {
// 创建引用数组, id是从1-10, 年级随机的[1-6], 分数是随机的[0~100]
Student[] stuArr = new Student[10];
for (int i = 0; i < stuArr.length; i++) {
int id = i + 1;
String name = "某同学";
int grade = (int) (Math.random() * 6 + 1);
double score = (int) (Math.random() * 101);
stuArr[i] = new Student(id, name, grade, score);
}
// 遍历数组, 也可以使用增强for
for (Student tmp : stuArr) {
System.out.println(tmp.say());
}
System.out.println("********************************************");
for (int i = 0; i < stuArr.length - 1; i++) {
for (int j = 0; j < stuArr.length - 1 - i; j++) {
if (stuArr[j].getScore() > stuArr[j + 1].getScore()) { // 如果j位置的同学的分数大于右侧j+1位置的同学的分数
Student tmp = stuArr[j];
stuArr[j] = stuArr[j + 1];
stuArr[j + 1] = tmp;
}
}
}
// 遍历数组, 也可以使用增强for
for (Student tmp : stuArr) {
System.out.println(tmp.say());
}
4.选择排序(改进版)
(1)以位置为主导,在适当的位置处保存适当的值。
(2)正确的位置放正确的值。
(3)排序数组
public static void main(String[] args) {
int[] arr = new int[8];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 20);
}
// 遍历
for (int tmp : arr) {
System.out.print(tmp + " ");
}
System.out.println();
for (int i = 0; i < arr.length - 1; i++) {
// 以i位置为基准位置, 然后要找出包括基准位置在内到右侧所有数中的最小值的下标.
int minIndex = i; // 最小值下标从基准位置开始
for (int j = i + 1; j < arr.length; j++) { // 找出基准位置右侧所有数中的最小值
if (arr[j] < arr[minIndex]) { // 如果j位置的值小于最小值下标处的值
minIndex = j; // 记录最小值下标
}
}
// 交换基准位置和最小值位置处的值, 让适当的位置保存适当的值
int tmp = arr[i];
arr[i] = arr[minIndex];// 最关键的归位, 让最小值放入基准位置
arr[minIndex] = tmp;
}
// 遍历
for (int tmp : arr) {
System.out.print(tmp + " ");
}
System.out.println();
}
(4)排序数组对象
public static void main(String[] args) {
// 创建引用数组, id是从1-10, 年级随机的[1-6], 分数是随机的[0~100]
Student[] stuArr = new Student[10];
for (int i = 0; i < stuArr.length; i++) {
int id = i + 1;
String name = "某同学";
int grade = (int) (Math.random() * 6 + 1);
double score = (int) (Math.random() * 101);
stuArr[i] = new Student(id, name, grade, score);
}
// 遍历数组, 也可以使用增强for
for (Student tmp : stuArr) {
System.out.println(tmp.say());
}
System.out.println("********************************************");
for (int i = 0; i < stuArr.length - 1; i++) {
// 以i位置为基准位置, 然后要找出包括基准位置在内到右侧所有数中的最小值的下标.
int minIndex = i; // 最小值下标从基准位置开始
for (int j = i; j < stuArr.length; j++) {
if (stuArr[j].getScore() < stuArr[minIndex].getScore()) {
minIndex = j;
}
}
// 交换基准位置和最小值位置处的值, 让适当的位置保存适当的值
Student tmp = stuArr[i];
stuArr[i] = stuArr[minIndex];
stuArr[minIndex] = tmp;
}
// 遍历数组, 也可以使用增强for
for (Student tmp : stuArr) {
System.out.println(tmp.say());
}
System.out.println("********************************************");
}
5.快速排序
/**
* @param arr 要排序的数组
* @param begin 开始索引 包含
* @param end 结束索引 不包含
*/
public static void quick(int[] arr, int begin, int end) {
if (begin >= end) { // 如果开始索引大于等于结束索引, 就结束递归
return;
}
int key = arr[begin]; // 取开始位置的值为键值
int keyIndex = begin; // 用于控制比键小的值的保存和最终键值的保存位置
for (int i = begin + 1; i < end; i++) {
if (arr[i] < key) {
keyIndex++; // 控制把比key值小的值依次保存在右侧
int tmp = arr[keyIndex];
arr[keyIndex] = arr[i]; // 把key值小的值归位
arr[i] = tmp;
}
}
// 交换开始位置和键位置
arr[begin] = arr[keyIndex];
arr[keyIndex] = key; // 键值归位, 分区完成.
// 递归左子列和右子列
quick(arr, begin, keyIndex);
quick(arr, keyIndex + 1, end);
}
public static void main(String[] args) {
int[] arr = new int[8];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 20);
}
// 遍历
for (int tmp : arr) {
System.out.print(tmp + " ");
}
System.out.println();
quick(arr, 0, arr.length);
//Arrays.sort(arr); // 默认使用的就是快速排序
// 遍历
for (int tmp : arr) {
System.out.print(tmp + " ");
}
System.out.println();
}
6.多维数组
(1)数组的数组
(2)数组的元素就是子数组
(3)格式1(动态初始化)
int[][] arr = new int[3][2];
(4)格式2(动态初始化)
int[][] arr = new int[3][];
arr[0] = new int[1];
arr[1] = new int[2];
arr[2] = new int[3];
(5)非法:int[][] arr = new int[][3];
(6)二维数组的遍历、求和、平均值
public static void main(String[] args) {
int[][] arrarr = new int[5][]; // 创建了一个具有5个子数组的二维数组. 数组中全部都是空洞
for (int i = 0; i < arrarr.length; i++) {
arrarr[i] = new int[i + 2];
for (int j = 0; j < arrarr[i].length; j++) {
arrarr[i][j] = (int)(Math.random() * 50);
}
}
// 遍历数组的数组
for (int i = 0; i < arrarr.length; i++) {
int[] child = arrarr[i];
for (int j = 0; j < child.length; j++) {
System.out.print(child[j] + " ");
}
System.out.println();
}
// 求平均值
int sum = 0;
int count = 0;
for (int[] child : arrarr) {
for (int tmp : child) {
sum += tmp;
count++;
}
}
int avg = sum / count;
System.out.println("avg : " + avg);
}