Day8:排序,Array类
1.排序基础
排序的基础即交换两个变量的值
-
通过第三个变量来交换
//a = 1,b = 2 int c = a;//c = 1 a = b;//a = 2 b = c;//b = 1 //完成交换
-
通过加减法计算(也可以通过乘除…小数)
//a = 1,b = 2 a = a + b;//a = 3 b = a - b;//b = 1 a = a - b;//a = 2
-
不通过第三个变量且高效
//a = 1,b = 2 a = a + b - (b = a); //完成交换
-
通过位运算
//a = 1,b = 2 a = a ^ b; //a 0001 //b 0010 //a=0011 b = a ^ b; //a 0011 //b 0010 //b=0001 a = a ^ b; //a 0011 //b 0001 //a=0010 //完成交换
2.最大值最小值算法
public class Test18 {
public static void main(String[] args) {
int[] a = { 12, 34, 45, 56, 67, 23, 45, 134 };
int max = max(a);
System.out.println(max);
int min = max(a);
System.out.println(min);
}
public static int max(int[] x) {
int max = x[0];
for (int i = 0; i < x.length; i++) {
if (x[i] > max) {
max ^= x[i];
x[i] ^= max;
max ^= x[i];
}
}
return max;
}
public static int min(int[] x) {
int min = x[0];
for (int i = 0; i < x.length; i++) {
if (x[i] < min) {
min ^= x[i];
x[i] ^= min;
min ^= x[i];
}
}
return min;
}
}
3.冒泡排序Key
相邻两数两两相比较,大的放右边;
比较完一轮,确定右边大数为最大数;
以此类推,共比较(n-1)轮;
import java.util.Arrays;
public class MaoPao_a {
public static void main(String[] args) {
int[] nums = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};//待排序待数列
System.out.println("原数组:");
System.out.println(Arrays.toString(nums));
System.out.println("运算过程:");
// 外循环控制轮数
// 比较轮数=数组长度-1
for (int i = 0; i < nums.length - 1; i++) {
for (int j = 0; j < nums.length - 1 - i; j++) {
if (nums[j] > nums[j + 1]) {
nums[j] = nums[j] + nums[j + 1];
nums[j + 1] = nums[j] - nums[j + 1];
nums[j] = nums[j] - nums[j + 1];
}
}
System.out.println(Arrays.toString(nums));
}
System.out.println("最终结果:");
System.out.println(Arrays.toString(nums));
}
}
/*
原数组:
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
运算过程:
[8, 7, 6, 5, 4, 3, 2, 1, 0, 9]
[7, 6, 5, 4, 3, 2, 1, 0, 8, 9]
[6, 5, 4, 3, 2, 1, 0, 7, 8, 9]
[5, 4, 3, 2, 1, 0, 6, 7, 8, 9]
[4, 3, 2, 1, 0, 5, 6, 7, 8, 9]
[3, 2, 1, 0, 4, 5, 6, 7, 8, 9]
[2, 1, 0, 3, 4, 5, 6, 7, 8, 9]
[1, 0, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
最终结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
*/
3.选择排序Key
设第一个元素最小,依次与后面元素比较
如果不是最小则交换,第一轮确定一个元素最小
第二轮假设第二个元素最小;以此类推
import java.util.Arrays;
public class XuanZe {
public static void main(String[] args) {
int[] a = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };// 待排序待数列
System.out.println("原数组:");
System.out.println(Arrays.toString(a));
System.out.println("运算过程:");
// 外层确定轮数
for (int i = 0; i < a.length - 1; i++) {
for (int j = i; j < a.length - 1; j++) {
if (a[i] > a[j + 1]) {
// int t = a[i];
// a[i] = a[j + 1];
// a[j + 1] = t;
a[j + 1] = a[i] + a[j + 1];
a[i] = a[j + 1] - a[i];
a[j + 1] = a[j + 1] - a[i];
}
}
System.out.println(Arrays.toString(a));
}
System.out.println("最终结果:");
System.out.println(Arrays.toString(a));
}
}
import java.util.Arrays;
public class XuanZe_b {
public static void main(String[] args) {
int[] a = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };// 待排序待数列
System.out.println("原数组:");
System.out.println(Arrays.toString(a));
System.out.println("运算过程:");
int minIndex;
for (int i = 0; i < a.length - 1; i++) {
minIndex = i;
for (int j = i + 1; j < a.length; j++) {
if (a[minIndex] > a[j]) {
minIndex = j;
}
// 判断需要交换的数下标是否为i
if (minIndex != i) {
a[minIndex] = a[minIndex] + a[i];
a[i] = a[minIndex] - a[i];
a[minIndex] = a[minIndex] - a[i];
}
}
System.out.println(Arrays.toString(a));
}
System.out.println("最终结果:");
System.out.println(Arrays.toString(a));
}
}
4.插入排序
public class Test20 {
public static void main(String[] args) {
int[] nums = { 5, 4, 3, 2, 1, 0 };// 待排序待数列
// 控制比较轮数
for (int i = 1; i < nums.length; i++) {
// 每轮开始,选择下一个数,临时存放其值,并开始比较
System.out.println("~~~~~这是第" + i + "轮~~~~~~~~");
int temp = nums[i];
int j = 0;
for (j = i - 1; j >= 0; j--) {
if (nums[j] > temp) {
nums[j + 1] = nums[j];
} else {
break;
}
// 输出过程
for (int n : nums) {
System.out.print(n + " ");
}
System.out.println();
}
// 上面带j的for循环结束一轮,j-1了,这里需要+1
if (nums[j + 1] != temp) {
nums[j + 1] = temp;
}
// 输出过程
for (int n : nums) {
System.out.print(n + " ");
}
System.out.println();
}
System.out.println("===最终结果========");
// 输出结果
for (int n : nums) {
System.out.print(n + " ");
}
}
}
/*
~~~~~这是第1轮~~~~~~~~
5 5 3 2 1 0
4 5 3 2 1 0
~~~~~这是第2轮~~~~~~~~
4 5 5 2 1 0
4 4 5 2 1 0
3 4 5 2 1 0
~~~~~这是第3轮~~~~~~~~
3 4 5 5 1 0
3 4 4 5 1 0
3 3 4 5 1 0
2 3 4 5 1 0
~~~~~这是第4轮~~~~~~~~
2 3 4 5 5 0
2 3 4 4 5 0
2 3 3 4 5 0
2 2 3 4 5 0
1 2 3 4 5 0
~~~~~这是第5轮~~~~~~~~
1 2 3 4 5 5
1 2 3 4 4 5
1 2 3 3 4 5
1 2 2 3 4 5
1 1 2 3 4 5
0 1 2 3 4 5
===最终结果====
0 1 2 3 4 5
*/
5.二分查找算法
- 二分法查找(折半查找):前提是在已经排好序的数组中,通过将待查找的元素与中间索引值对应的元素进行比较,若大于中间索引值对应的元素,去右半部分查找,否则,去左半部分查找。依此类推。直到找到为止;找不到返回一个负数。
package com.qf.Day0Demo;
public class Test21 {
public static void main(String[] args) {
// 必须有序
int[] num = { 22, 33, 44, 55, 66, 77, 88, 99, 100 };
int index = binarySearch(num, 100);//输出为8
System.out.println(index);
}
//二分查找算法
public static int binarySearch(int[] num, int key) {
int start = 0;// 开始下标
int end = num.length - 1;// 结束下标
while (start <= end) {
// 无符号右移一位equals除二
int middle = (start + end) >>> 1;
if (num[middle] > key) {
end = middle - 1;
} else if (num[middle] < key) {
start = middle + 1;
} else {
return middle;
}
}
return -1;
}
}
6.系统排序
import java.util.Arrays;
//系统提供的排序方法
public class SystemTest {
public static void main(String[] args) {
int[] a = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };// 待排序待数列
System.out.println("原数组:");
System.out.println(Arrays.toString(a));
Arrays.sort(a);// 数组排序的方法
System.out.println("最终结果:");
System.out.println(Arrays.toString(a));
}
}
7.Array工具类
常用方法:
-
使用二分法查找
int[] num = { 6, 4, 5, 3, 1, 2 }; int index = Arrays.binarySearch(num, 5); System.out.println("我们找到的下标是" + index);// 2
-
数组 内容转成字符串的 形式输出
// foreach输出数组 for (int n : num) { System.out.println(n); } // 调用Array输出数组 // 在测试输出数据时,可以使用,更加方便 System.out.println(Arrays.toString(num));
-
数组排序
//系统快速排序 Arrays.sort(num); System.out.println(Arrays.toString(num));
-
复制指定的数组
int[] num = { 6, 4, 5, 3, 1, 2 }; // 数组的复制(也是常用数组扩容) System.out.println("数组的复制和扩容"); int[] num2 = Arrays.copyOf(num, 10); System.out.println(Arrays.toString(num2)); // 复制数组指定区间 // 1. //第一个位置确定要复制的数组, //第二个位置确定起始下标, //第三个位置确定结束下标(可以超出) System.out.println("数组复制指定区间1"); int[] num3 = Arrays.copyOfRange(num, 3, 8); System.out.println(Arrays.toString(num3)); // 2. //第一个位置确定要复制的数组 //第二个位置确定原数组开始复制的起始位置,空数组必须为0 //第三个位置确定要起始下标 //第四个位置确定结束下标,不能超过目标数组的最大下标,小于的话未被赋值的数为0 System.out.println("数组复制指定区间2"); int[] num4 = new int[num.length]; System.arraycopy(num, 0, num4, 0, num.length-1); System.out.println(Arrays.toString(num4));
-
判断两个数组是否相等
System.out.println(Arrays.equals(num3, num4));
-
使用指定元素填充数组
Arrays.fill(num4, 0);//用0填充数组num4 System.out.println(Arrays.toString(num4));
package Test;
import java.util.Arrays;
public class Test24 {
public static void main(String[] args) {
int[] num = { 6, 4, 5, 3, 1, 2 };
// 二分查找
System.out.println("二分查找");
int index = Arrays.binarySearch(num, 98);
System.out.println("我们找到的下标是" + index);// 4
// 输出数组
System.out.println("输出数组");
for (int n : num) {
System.out.println(n);
}
// 调用Array输出数组
// 在测试输出数据时,可以使用,更加方便
System.out.println(Arrays.toString(num));
// 排序
System.out.println("系统快速排序");
Arrays.sort(num);// 快速排序
System.out.println(Arrays.toString(num));
// 数组的复制(也是常用数组扩容)
System.out.println("数组的复制和扩容");
int[] num2 = Arrays.copyOf(num, 10);
System.out.println(Arrays.toString(num2));
// 复制数组指定区间
// 1.
//第一个位置确定要复制的数组,
//第二个位置确定起始下标,
//第三个位置确定结束下标(可以超出)
System.out.println("数组复制指定区间1");
int[] num3 = Arrays.copyOfRange(num, 3, 8);
System.out.println(Arrays.toString(num3));
// 2.
//第一个位置确定要复制的数组
//第二个位置确定原数组开始复制的起始位置,空数组必须为0
//第三个位置确定要起始下标
//第四个位置确定结束下标,不能超过目标数组的最大下标,小于的话未被赋值的数为0
System.out.println("数组复制指定区间2");
int[] num4 = new int[num.length];
System.arraycopy(num, 0, num4, 0, num.length-1);
System.out.println(Arrays.toString(num4));
//小结:数组的复制
/*
效率由高到低的排序是:System.arraycopy-->Arrays.copyOf-->for
*/
//判断两个数组是否相等
System.out.println("判断两个数组是否相等");
System.out.println(Arrays.equals(num3, num4));
//填充数组
System.out.println("填充数组");
Arrays.fill(num4, 0);
System.out.println(Arrays.toString(num4));
}
}
/*
二分查找
我们找到的下标是-7
输出数组
6
4
5
3
1
2
[6, 4, 5, 3, 1, 2]
系统快速排序
[1, 2, 3, 4, 5, 6]
数组的复制和扩容
[1, 2, 3, 4, 5, 6, 0, 0, 0, 0]
数组复制指定区间1
[4, 5, 6, 0, 0]
数组复制指定区间2
[1, 2, 3, 4, 5, 0]
判断两个数组是否相等
false
填充数组
[0, 0, 0, 0, 0, 0]
二分查找
我们找到的下标是-7
输出数组
6
4
5
3
1
2
[6, 4, 5, 3, 1, 2]
系统快速排序
[1, 2, 3, 4, 5, 6]
数组的复制和扩容
[1, 2, 3, 4, 5, 6, 0, 0, 0, 0]
数组复制指定区间1
[4, 5, 6, 0, 0]
数组复制指定区间2
[1, 2, 3, 4, 5, 0]
判断两个数组是否相等
false
填充数组
[0, 0, 0, 0, 0, 0]
*/