Java数组算法

一、基于一维数组的一些算法

1、对数组的元素统计分析

案例需求

需求:随机产生10个[0,100)整数放到一个数组中,统计他们的总和,平均值。

public class ArrayArithmetic1 {
    public static void main(String[] args) {
        //需求:随机产生10个[0,100)整数放到一个数组中,统计他们的总和,平均值
        //(1)声明一个int[]数组,长度为10
        int[] arr = new int[10];

        //随机产生10个[0,100)整数放到arr数组中
        int sum = 0;
        double avg = 0.0;
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)(Math.random()*100);

            sum += arr[i];
            System.out.println(arr[i]);
        }
        System.out.println("总和:" +sum);
//        avg = sum/arr.length;// int/int 结果是int,然后升级为double
        avg = (double)sum/arr.length; //对sum提升为double
        System.out.println("平均值:" + avg);
    }
}
案例需求

需求:随机产生10个[0,100)整数放到一个数组中,统计他们中3的倍数的个数、5的倍数的个数。

public class ArrayArithmetic2 {
    public static void main(String[] args) {
        //需求:随机产生10个[0,100)整数放到一个数组中,统计他们中3的倍数的个数、5的倍数的个数
        //(1)声明一个int[]数组,长度为10
        int[] arr = new int[10];

        //随机产生10个[0,100)整数放到arr数组中
        int three = 0;
        int five = 0;
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)(Math.random()*100);
            System.out.print(arr[i]);

            /*if(arr[i] % 3 == 0){
                three++;
            }else if(arr[i] % 5 == 0){
                five++;
            }*///不对,如果满足35的倍数,只统计了3的倍数
            if(arr[i] % 3 == 0){
                three++;
                System.out.print("\t 3的倍数");
            }
            if(arr[i] % 5 == 0){
                five++;
                System.out.print("\t 5的倍数");
            }
            System.out.println();
        }
        System.out.println("three = " + three);
        System.out.println("five = " + five);
    }
}

2、在数组中找最大值

假设第一个元素最大

在这里插入图片描述

案例需求:随机产生10个[0,100)整数放到一个数组中,找出他们当中的最大值。

public class ArrayArithmetic3 {
    public static void main(String[] args) {
        //(1)声明一个int[]数组,长度为10
        int[] arr = new int[10];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * 100);
            System.out.print(arr[i]+" ");
        }
        System.out.println();

        /*
        找出最大值:
            (1)先假设第一个元素最大,用max记录该值
            (2)后续的元素一一与max变量比较,有比max还大的,修改max的值
            
         */
        int max = arr[0];
        for(int i=1; i<arr.length; i++){
            if(arr[i] > max){
                max = arr[i];
            }
        }
        System.out.println("max = " + max);
    }
}

把max初始化为一个比他们都小的数

在这里插入图片描述

public class ArrayArithmetic4 {
    public static void main(String[] args) {
        //案例需求:随机产生10个[0,100)整数放到一个数组中,找出他们当中的最大值
        int[] arr = new int[10];

        int max = 0; //max初始化为0或负数都可以,比所有元素都小
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)(Math.random()*100);
            System.out.print(arr[i] +" ");

            if(arr[i] > max){
                max = arr[i];
            }
        }
        System.out.println();
        System.out.println("max = " + max);
    }
}

public class ArrayArithmetic4 {
    public static void main(String[] args) {
        //案例需求:随机产生10个[0,100)整数放到一个数组中,找出他们当中的最大值
        int[] arr = new int[10];

//        int max = 0; //max初始化为0或负数都可以,比所有元素都小
        int max = Integer.MIN_VALUE; //int的最小值
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)(Math.random()*100);
            System.out.print(arr[i] +" ");

            if(arr[i] > max){
                max = arr[i];
            }
        }
        System.out.println();
        System.out.println("max = " + max);
    }
}

3、在数组中找最大值及其下标

情况一:元素没有重复的情况
思路一:

在这里插入图片描述

public class ArrayArithmetic5 {
    public static void main(String[] args) {
        int[] arr = {4, 5, 6, 1, 9};
        //元素都不重复,找最大值及其下标

        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 = " + max);
        System.out.println("index = [" + index +"]");
    }
}

思路二:

在这里插入图片描述

public class ArrayArithmetic5_2 {
    public static void main(String[] args) {
        int[] arr = {4, 5, 6, 1, 9};
        //元素都不重复,找最大值及其下标

        int maxIndex = 0;//最大值下标
        for(int i=1; i<arr.length; i++){
            if(arr[i] > arr[maxIndex]){
                maxIndex = i;
            }
        }
        System.out.println("maxIndex = [" + maxIndex +"]");
        System.out.println("最大值 = " + arr[maxIndex]);
    }
}
情况二:元素可能重复

此时最大值的下标可能有多个。

思路一:

在这里插入图片描述

public class ArrayArithmetic6 {
    public static void main(String[] args) {
        int[] arr = {4, 6, 1, 6, 9, 5, 9};
        
        //找到最大值,及其所有下标
        /*
        思路一:
        (1)先找到最大值
        (2)再遍历数组,看哪些元素和最大值一样
         */

        //先找到最大值
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(arr[i] > max){
                max = arr[i];
            }
        }
        System.out.println("max = " + max);
        //找出所有最大值的下标
        System.out.println("所有最大值的下标:");
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == max){
                System.out.print("[" + i+"] ");
            }
        }
    }
}

思路二:

在这里插入图片描述

public class ArrayArithmetic6_2 {
    public static void main(String[] args) {
        int[] arr = {4, 6, 1, 6, 9, 5, 9};

        //找到最大值,及其所有下标
        /*
        思路二:
        (1)用max表示最大值
        (2)用indexStr 表示最大值的所有下标,indexStr是String类型
         */
        int max = arr[0];
        String indexStr = "0";

        for(int i=1; i<arr.length; i++){
            if(arr[i] > max){
                max = arr[i];
                indexStr = i + "";//重新赋值
            }else if(arr[i] == max){
                indexStr = indexStr + "," + i;//拼接下标
            }
        }
        System.out.println("max = " + max);
        System.out.println("indexStr = [" + indexStr+"]");
    }
}

4、数组的反转

在这里插入图片描述

public class ArrayArithmetic7 {
    public static void main(String[] args) {
        int[] arr = {4, 5, 6, 1, 9};
        //需求:将数组元素反转,结果:{9,1,6,5,4}

        System.out.println("交换前:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();

        for(int left=0,right=arr.length-1; left<right; left++,right--){
            int temp = arr[left];
            arr[left] =arr[right];
            arr[right] = temp;
        }

        //交换后的结果:
        System.out.println("交换后:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }
}

5、在数组中查找元素

情况一:数组元素无序(顺序查找)

在这里插入图片描述

public class ArrayArimetic8 {
    public static void main(String[] args) {
        int[] arr = {4, 5, 6, 1, 9};
        int target = 1;

        int index = -1;//这里设置为[0, arr.length-1]以外的数都可以,习惯上用-1,表示非正常下标
//        boolean flag = false;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == target){
                index = i;
//                flag = true;
                break;
            }
        }

/*        if(flag){
            System.out.println(target +"在数组存在");
        }else{
            System.out.println(target +"在数组不存在");
        }*/


        if(index == -1){
            System.out.println(target +"在数组不存在");
        }else{
            System.out.println(target +"在数组存在,下标是:[" +index + "]");
        }

    }
}

情况二:数组元素有序
(1)顺序查找

在这里插入图片描述

public class ArrayArimetic8_2 {
    public static void main(String[] args) {
        int[] arr = {1, 5, 8, 9, 15};//元素是有序的,从小到大
        int target = 7;

        //顺序查找
        int index = -1;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == target){
                index = i;
                break;
            }else if(arr[i] > target){
                break;
            }
        }
        if(index == -1){
            System.out.println(target +"在数组不存在");
        }else{
            System.out.println(target +"在数组存在,下标是:[" +index + "]");
        }
    }
}

(2)二分查找

在这里插入图片描述

在这里插入图片描述

public class ArrayArithmetic9 {
    public static void main(String[] args) {
        int[] arr = {8,15,23,35,45,56,75,85};
        int target = 100;

        int index = -1;
        for(int left=0,right=arr.length-1; left<=right; ){
//            int mid = (left+right)/2;
            int mid = left + (right-left)/2;
            if(target == arr[mid]){
                index = mid;
                break;
            }else if(target > arr[mid]){
                //说明 目标值可能在本次查找范围的右边,修改查找范围
                left = mid + 1;
            }else{
                //说明 目标值可能在本次查找范围的左边,修改查找范围
                right = mid - 1;
            }
        }


        if(index == -1){
            System.out.println(target +"在数组不存在");
        }else{
            System.out.println(target +"在数组存在,下标是:[" +index + "]");
        }
    }
}

6、数组的排序

在这里插入图片描述

(1)直接选择排序

在这里插入图片描述

public class ArrayArithmetic10 {
    public static void main(String[] args) {
        //直接选择排序
        int[] arr = {6, 9, 2, 9, 1};

        /*
        n个元素,需要找n-1个最小值
         */
        for(int i=0; i<arr.length-1; i++){
            //先找本轮的最小值
            /*
            当i=0,第1轮,要查找最小值的范围:arr[0] ~ arr[4],它应该在arr[0]位置
            当i=1,第2轮,要查找最小值的范围:arr[1] ~ arr[4],它应该在arr[1]位置
            当i=2,第3轮,要查找最小值的范围:arr[2] ~ arr[4],它应该在arr[2]位置
            当i=3,第4轮,要查找最小值的范围:arr[3] ~ arr[4],它应该在arr[3]位置
             */
            //看该最小值是否在它应该在的位置,如果不在它应该在的位置,交换

            int min = arr[i];//假设本轮待排序元素的第1个元素最小
            int index = i;//最小值的下标
            //在arr[i+1] ~ arr[arr.length-1] 范围内查看是否有比min还小的元素
            for(int j=i+1; j<arr.length; j++){
                if(arr[j] < min){
                    min = arr[j];
                    index = j;
                }
            }

            //本轮最小值现在在arr[index], 它应该arr[i]位置
            if(index != i){
                int temp = arr[i];
                arr[i] = arr[index];
                arr[index] = temp;
            }
        }

        //查看排序结果
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +" ");
        }
        System.out.println();
    }
}

(2)冒泡排序

在这里插入图片描述

冒泡排序基本实现
public class ArrayArithmetic11 {
    public static void main(String[] args) {
        int[] arr = {6, 9, 2, 9, 1};
        /*
        n个元素,需要n-1轮
         */
        for(int i=0; i<arr.length-1; i++){
            /*
            i=0, 要比较的数的范围arr[0]~arr[4]
                arr[0]~ arr[1]  j=0, arr[j]~arr[j+1]
                arr[1]~ arr[2]  j=1, arr[j]~arr[j+1]
                arr[2]~ arr[3]  j=2, arr[j]~arr[j+1]
                arr[3]~ arr[4]  j=3, arr[j]~arr[j+1]
                for(int j=0; j<arr.length-1; j++)
            i=1,要比较的数的范围arr[0]~arr[3]
                arr[0]~ arr[1]  j=0, arr[j]~arr[j+1]
                arr[1]~ arr[2]  j=1, arr[j]~arr[j+1]
                arr[2]~ arr[3]  j=2, arr[j]~arr[j+1]
                for(int j=0; j<arr.length-2; j++)
            i=2, 要比较的数的范围arr[0]~arr[2]
                arr[0]~ arr[1]  j=0, arr[j]~arr[j+1]
                arr[1]~ arr[2]  j=1, arr[j]~arr[j+1]
                for(int j=0; j<arr.length-3; j++)
            i=3,要比较的数的范围arr[0]~arr[2]
                arr[0]~ arr[1]  j=0, arr[j]~arr[j+1]
                for(int j=0; j<arr.length-4; j++)

                for(int j=0; j<arr.length-1-i; j++)
             */
            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;
                }
            }

        }

        //输出排序结果
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +" ");
        }
        System.out.println();

    }
}

i=1开始的写法如下:

public class ArrayArithmetic11_2 {
    public static void main(String[] args) {
        int[] arr = {6, 9, 2, 9, 1};
        /*
        n个元素,需要n-1轮
         */
        for(int i=1; i<arr.length; i++){
            /*
            i=1, 要比较的数的范围arr[0]~arr[4]
                arr[0]~ arr[1]  j=0, arr[j]~arr[j+1]
                arr[1]~ arr[2]  j=1, arr[j]~arr[j+1]
                arr[2]~ arr[3]  j=2, arr[j]~arr[j+1]
                arr[3]~ arr[4]  j=3, arr[j]~arr[j+1]
                for(int j=0; j<arr.length-1; j++)
            i=2,要比较的数的范围arr[0]~arr[3]
                arr[0]~ arr[1]  j=0, arr[j]~arr[j+1]
                arr[1]~ arr[2]  j=1, arr[j]~arr[j+1]
                arr[2]~ arr[3]  j=2, arr[j]~arr[j+1]
                for(int j=0; j<arr.length-2; j++)
            i=3, 要比较的数的范围arr[0]~arr[2]
                arr[0]~ arr[1]  j=0, arr[j]~arr[j+1]
                arr[1]~ arr[2]  j=1, arr[j]~arr[j+1]
                for(int j=0; j<arr.length-3; j++)
            i=4,要比较的数的范围arr[0]~arr[2]
                arr[0]~ arr[1]  j=0, arr[j]~arr[j+1]
                for(int j=0; j<arr.length-4; j++)

                for(int j=0; j<arr.length-i; j++)
             */
            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 ArrayArithmetic11_3 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        /*
        n个元素,需要n-1轮

        如果中途发现数组已经有序了,可以提前结束排序过程。
        思考:怎么证明数组已经有序了?
            如果某一轮下来,没有进入过if,说明数组已经有序了
         */
        for(int i=1; i<arr.length; i++){
            boolean flag = true;//假设已经有序了
            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;
                    flag = false;//还未有序
                }
            }
            if(flag){
                break;
            }
        }

        //输出排序结果
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +" ");
        }
        System.out.println();

    }
}

二、二维数组

为什么要使用二维数组?

一维数组是用来管理一组相同数据类型的数据的。例如:存储和管理一组学员的成绩。

二维数组是用来管理多组相同数据类型的数据的。例如:分别存储和管理多组(咱们班5个小组)学员的成绩。

二维数组的声明和使用

声明格式
元素的数据类型[][] 二维数组名; //标准写法,推荐写法

元素的数据类型 二维数组名[][];
元素的数据类型[] 二维数组名[];
初始化
1、静态的初始化
元素的数据类型[][] 二维数组名 = {{第一组的元素列表},{第二组的元素列表},{第三组的元素列表},...};

元素的数据类型[][] 二维数组名 = new 元素的数据类型[][]{{第一组的元素列表},{第二组的元素列表},{第三组的元素列表},...};
int[][] arr = {
                {5,6,8,9,1},
                {5,3,24,2},
                {6,9,8,7}
        };
2、动态初始化之规则的二维数组

规则的二维数组是指每一行的元素个数是相同的。

元素的数据类型[][] 二维数组名 = new 元素的数据类型[行数量][每一行的元素个数];
int[][] arr = new int[3][5];//代表有3行,每一行有5个元素
3、动态初始化之不规则的二维数组

不规则的二维数组是指每一行的元素个数是可能不相同的。

元素的数据类型[][] 二维数组名 = new 元素的数据类型[行数量][]; //小细节,右边第2个[]是空的,表示暂时不能确定每一行有几个元素
二维数组名[行下标] = new 元素的数据类型[该行的元素个数(或长度)];
int[][] arr = new int[3][];//代表有3行,每一行的元素个数还未定
arr[0] = new int[5];//给第一行申请5个元素的内存空间
arr[1] = new int[3];//给第二行申请3个元素的内存空间
arr[2] = new int[10];//给第三行申请10个元素的内存空间
4、代码演示
public class TwoDimensionalArrayDemo1 {
    public static void main(String[] args) {
        int[][] arr = {
                {5,6,8,9,1},
                {5,3,24,2},
                {6,9,8,7}
        };

        System.out.println("二维数组的长度(行数):" + arr.length);
        System.out.println("第一行:" + arr[0]);//[I@4dd8dc3

        for(int i=0; i<arr.length; i++){//代表有几行,有几组
            for(int j=0; j<arr[i].length; j++){//遍历每一行的 n个元素,  arr[i]是一行,又是一个一维数组。
                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }
    }
}

public class TwoDimensionalArrayDemo2 {
    public static void main(String[] args) {
        int[][] arr = new int[3][5];

        System.out.println("二维数组的长度(行数):" + arr.length);
        System.out.println("第一行:" + arr[0]);//[I@4dd8dc3

        for(int i=0; i<arr.length; i++){//代表有几行,有几组
            for(int j=0; j<arr[i].length; j++){//遍历每一行的 n个元素,  arr[i]是一行,又是一个一维数组。
                arr[i][j] = (int)(Math.random()*100);//随机产生[0,100)的整数,放到二维数组中

                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }
    }
}

public class TwoDimensionalArrayDemo3 {
    public static void main(String[] args) {
        int[][] arr = new int[3][];

        System.out.println("二维数组的长度(行数):" + arr.length);
        System.out.println("第一行:" + arr[0]);//null
        //表示第一行有几个元素还未确定,堆内存中还没有分配第1行的内存空间,所以是null
//        System.out.println("第一行的第一个元素:" + arr[0][0]);//java.lang.NullPointerException: 空指针异常
        //arr[0]不指向任何内存位置,所以内存中找不到 arr[0][0]元素

        arr[0] = new int[5];//给第一行申请5个元素的内存空间
        //arr[0]这个[0]是下标的意思,
        //int[5]这是[5]是元素的个数的意思
        //原则:数组名后面[]里面是下标
        //原则:数据类型后面[]里面是长度,元素个数
        System.out.println("第一行的第一个元素:" + arr[0][0]);//0
        arr[1] = new int[3];//给第二行申请3个元素的内存空间
        arr[2] = new int[10];//给第三行申请10个元素的内存空间

        for(int i=0; i<arr.length; i++){//代表有几行,有几组
            for(int j=0; j<arr[i].length; j++){//遍历每一行的 n个元素,  arr[i]是一行,又是一个一维数组。
                arr[i][j] = (int)(Math.random()*100);//随机产生[0,100)的整数,放到二维数组中

                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }
    }
}

二维数组的遍历

int[][] arr = {
                {5,6,8,9,1},
                {5,3,24,2},
                {6,9,8,7}
        };

二维数组的长度:二维数组名.length ,代表一共有几组。 例如:arr.length的值为3

二维数组的某一行/组:二维数组名[行下标],例如arr数组有3行

  • 第1行:arr[0],代表一个一维数组,{5,6,8,9,1},它也有长度,长度为5, arr[0].length的值为5
  • 第2行:arr[1],代表一个一维数组,{5,3,24,2},它也有长度,长度为4, arr[1].length的值为4
  • 第3行:arr[2],代表一个一维数组,{6,9,8,7},它也有长度,长度为4, arr[2].length的值为4
  • 二维数组的一行,是一个一维数组,二维数组可以看成元素是一维数组的一维数组。

二维数组的某一行的某一个元素:二维数组名[行下标][列下标]

  • 第1行的第1个元素:arr[0][0]
  • 第2行的第3个元素:arr[1][2]
for(int i=0; i<二维数组名.length; i++){
    for(int j=0; j<二维数组名[i].length; j++){
        System.out.print(二维数组名[i][j]);
    }
    System.out.println();
}

二维数组的内存分析

	int[][] arr = {
                {5,6,8,9,1},
                {5,3,24,2},
                {6,9,8,7}
        };
          {6,9,8,7}
    };

二维数组的长度:二维数组名.length   ,代表一共有几组。  例如:arr.length的值为3

二维数组的某一行/组:二维数组名[行下标],例如arr数组有3行

- 第1行:arr[0],代表一个一维数组,{5,6,8,9,1},它也有长度,长度为5, arr[0].length的值为5
- 第2行:arr[1],代表一个一维数组,{5,3,24,2},它也有长度,长度为4, arr[1].length的值为4
- 第3行:arr[2],代表一个一维数组,{6,9,8,7},它也有长度,长度为4, arr[2].length的值为4
- 二维数组的一行,是一个一维数组,二维数组可以看成元素是一维数组的一维数组。

二维数组的某一行的某一个元素:二维数组名\[行下标][列下标]

- 第1行的第1个元素:arr\[0][0]
- 第2行的第3个元素:arr\[1][2]

```java
for(int i=0; i<二维数组名.length; i++){
    for(int j=0; j<二维数组名[i].length; j++){
        System.out.print(二维数组名[i][j]);
    }
    System.out.println();
}

二维数组的内存分析

	int[][] arr = {
                {5,6,8,9,1},
                {5,3,24,2},
                {6,9,8,7}
        };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值