数组常见算法汇总
1、寻找数组中的最大值 | 最小值
`
public class max_min {
public static void main(String[] args) {
int[] nums = {10,20,30,40,33,22,11,8};
//1.创建一个变量,用于存储遍历数组发现的最大值
int n = nums[0];
for (int i = 1; i < nums.length; i++) {
n=n>nums[i]?n:nums[i];
//三目运算符 如果 n>nums[i] n的值不变 如果n<nums[i]的值 把nums[i]的值给n
}
int m = nums[0];
for (int i = 1; i < nums.length; i++) {
m=m<nums[i]?m:nums[i];
//三目运算符 如果 m<nums[i] m的值不变 如果m>nums[i]的值 把nums[i]的值给m
}
System.out.println("数组最大值为:"+n+"最小值为:"+m);
}
}
2、冒泡排序
原理:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
public class demon {
public static void main(String[] args) {
int[] nums = {20,15,18,13,30,60};
//外层循环控制的是,比较的轮数
//外层循环次数 length-1
int temp;
for (int i = 0; i < nums.length-1; i++) {
//内层循环控制的是每轮比较的次数
//第i轮(i从0开始计算),比较次数为:length-i-1
for (int j = 0; j < nums.length - i - 1; j++) {
if (nums[j]>nums[j+1]){
//两两相比,满足移动条件
temp = nums[j];
nums[j]=nums[j+1];
nums[j+1]=temp;
}
}
}
//排序已完成,下面是遍历打印查看的过程
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i]+" ");
}
}
}
升序排列的口诀:
N个数字来排队
两两相比小靠前,
外层 循环length-1
内层循环length-i-1
降序排序的口诀:
N个数字来排队
两两相比大靠前,
外层 循环length-1
内层循环length-i-1
3、二分查找(折半查找)
概述
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,二分查找要求数组数据必须采用顺 序存储结构有序排列。
原理
首先,假设数组中元素是按升序排列,将数组中间位置的数据与查找数据比较,如果两者相等,则查找成功;否则利用 中间位置记录将数组分成前、后两个子数组,如果中间位置数据大于查找数据,则进一步查找前子数组,否则进一步查 找后子数组。
重复以上过程,直到找到满足条件的数据,则表示查找成功, 直到子数组不存在为止,表示查找不成功
示例
public class demon2 {
/**
* 二分查找(折半查找)
*/
public static void main(String[] args) {
int[] nums = {10,20,30,40,50,60,70,80,90};
//要查找的数据
int num = 20;
//关键的三个变量:
//1. 最小范围下标
int minIndex = 0;
//2. 最大范围下标
int maxIndex = nums.length-1;
//3. 中间数据下标
int centerIndex = (minIndex+maxIndex)/2;
while(true) {
System.out.println("循环了一次");
if(nums[centerIndex]>num) {
//中间数据较大
maxIndex = centerIndex-1;
}else if(nums[centerIndex]<num) {
//中间数据较小
minIndex = centerIndex+1;
}else {
//找到了数据 数据位置:centerIndex
break;
}
if(minIndex > maxIndex) {
centerIndex = -1;
break;
}
//当边界发生变化, 需要更新中间下标
centerIndex = (minIndex+maxIndex)/2;
}
System.out.println("位置:"+centerIndex);
}
}
4、数组动态扩容(重点)
Java中实现数组动态扩容的两种方法
java中初始化一个数组需要定义数组的容量,而在我们使用数组时往往会遇到数组容量不够的情况,此时我们就需要通过动态扩容的方式来来根据需求扩大数组的容量。
我们可以通过两种方法来实现数组的动态扩容,一种是通过创建一个新的数组来覆盖旧数组,从而实现扩大数组容量的目的;另一种则是是通过java.util.Arrays类库来实现动态扩容。
4.1、新数组覆盖旧数组
当我们需要对数组进行扩容时,可以考虑不扩容数组本身,而是通过定义一个容量更大的数组,然后让原数组名称重新等于大数组即可。由于原数组数据在堆中,失去引用会被 GC 自动回收。示例如下:
public static void main(String[] args) {
int[] arr = {1,3,4};
//定义一个容量为3的数组arr
int[] arr2 =new int[arr.length+1];
//定义一个新数组arr2,容量比arr大1
for(int i=0;i<arr.length;i++){
//通过循环给新数组赋值
arr2[i]=arr[i];
} //新数组覆盖旧数组
arr = arr2;
System.out.println(arr.length);
//打印结果为4,数组扩容成功
}
我们可以通过定义的新数组arr2的名称直接覆盖掉旧数组arr,原数组被自动回收,从而实现了数组的扩容,因此我们可以根据这个思路进行数组的动态扩容。目标如下:
定义一个容量为1的数组,将系统输入的内容添加到数组中,并每添加一次对数组进行一次扩容。
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] arr = new int[1];
//定义一个容量为1的数组arr
int i =0;
while(true) { //通过死循环来观察多次动态扩容的结果
int x = input.nextInt();//接收int类型的输入
arr[i] = x;//将输入传递给数组arr
System.out.println(arr[i]);
int[] arr2 = new int[arr.length + 1];
//定义一个新数组arr2,容量比arr大1
//通过循环对新数组赋值
for(int j=0;j<arr.length;j++){
arr2[j] = arr[j];
}
arr = arr2;
//新数组覆盖旧数组
i++;
System.out.println(Arrays.toString(arr));
//打印数组内的值
}
}
输出的结果如下
4.2、调用Arrays类实现动态扩容
除了新数组覆盖旧数组的暴力扩容法外,我们还可以通过调用系统自带的java.util.Arrays类中的方法对数组进行动态扩容。Arrays类中实现数组扩容的方法为copyof。(需要导入java.util.Arrays)copyof方法的扩容原理为使用零复制指定的数组,截断或填充(如有必要),以使副本具有指定的长度,调用格式为Arrays.copyof(原数组名,扩容后的数组大小)。示例如下:
public class ArrayTest {
public static void main(String[] args) { //定义一个容量为3的数组arr
int[] arr = {1, 3, 4};
//将数组arr扩容到7
arr = Arrays.copyOf(arr,7);
//给扩容后的数组下标6定义一个值
arr[6] = 5;
//打印新数组
System.out.println(Arrays.toString(arr));
}
}
同样我们也使用Arrays类来实现数组的动态扩容,目标如下:
定义一个大小为1的数组,每次输入三个数字,按从大到小的顺序定义到数组中,数组不够的位置通过Arrays类来实现数组的扩容。
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int i = 3; //定义一个容量为3的数组arr
int[] arr = {1, 3, 4};
while(true) { //输入要添加的三个数字,分别定义为x1,x2,x3
System.out.println("请输入三个数字");
int x1 = input.nextInt();
int x2 = input.nextInt();
int x3 = input.nextInt(); //将数组arr扩容3,并在扩容的位置分别赋值x1,x2,x3
arr = Arrays.copyOf(arr, arr.length + 3);
arr[i] = x1;
arr[i+1] = x2;
arr[i+2] = x3;
i = i + 3; //打印新数组
System.out.println(Arrays.toString(arr));
}
}
输出如下