[ java基础 ] 数组: 反转.冒泡排序.二分查找.动态扩容.二维数组

数组

数组的应用

基础应用:针对数组中元素的顺序和数据值不做任何改变

​ 案例:求和,求最值,…

中级应用:针对数组中的地址值的改变,原数组的顺序和数据值不做任何改变

​ 案例:动态扩容,删除,插入

高级应用:针对原数组进行操作,不改变地址值,改变元素的顺序和数据值

​ 案例:反转,排序

  • 遍历数组及打印
public class ArrayDemo01 {
    public static void main(String[] args) {
        //声明初始化数组
        int[] arr = {11,22,33,44,55};

        //按照固定格式进行字符串拼接
        System.out.print("数组:[");

        //遍历数组
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                System.out.println(arr[i] + "]");
            } else {
                System.out.print(arr[i] + ", ");
            }
        }
    }
}
  • 数组的求和
public class ArrayDemo02 {
    public static void main(String[] args) {
        //声明初始化数组
        int[] arr = {11,22,33};

        //声明初始化求和变量
        int sum = 0;

        //遍历数组
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }

        //打印输出求和变量
        System.out.println("sum = " + sum);
    }
}
  • 获取数组中所有元素的最大值
public class ArrayDemo03 {
    public static void main(String[] args) {
        //声明初始化数组
        int[] arr = {5,15,2000,10000,100,4000};

        //声明初始化临时最大值变量
        int max = arr[0];

        //遍历数组
        for (int i = 1; i < arr.length; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }

        //打印输出最大值变量
        System.out.println("max = " + max);
    }
}
  • 评委打分

有10位评委为参赛的选手打分,分数分别为:5,4,6,8,9,0,1,2,7,3.求选手的最后得分(去掉一个最高分和一个最低分后其余8位评委打分的平均值)

ps:赋值平均分(double)应在赋值符号右边插入*1.0(double)

public class ArrayDemo04 {
    public static void main(String[] args) {
        //声明初始化存储评委分数的数组
        int[] arr = {5,4,6,8,9,0,1,2,7,3};

        //获取十位评委的总分
        int sum = arr[0];
        //获取评委中的最高分
        int max = arr[0];
        //获取评委中的最低分
        int min = arr[0];

        for (int i = 1; i < arr.length; i++) {
            sum += arr[i];

            if (max < arr[i]) {
                max = arr[i];
            }

            if (min > arr[i]) {
                min = arr[i];
            }
        }

        //获取选手最后得分
        double avg = (sum - max - min) * 1.0 / (arr.length - 2);

        System.out.println("avg = " + avg);
    }
}

  • 数组的反转

针对数组中元素依次进行首尾交换位置:

  1. 确定待交换位置的元素的索引位置
  2. 待交换位置的索引移动规律
  3. 进行索引位置上元素交换的前提条件
  4. 如何进行两个元素的位置交换?
  5. 获取start和end之间的关系(三种表示方式)
public class ArrayDemo05 {
    public static void main(String[] args) {
        //声明初始化数组
        int[] arr = {11,22,33,44,55,66};

        //进行数组反转前的打印
        System.out.print("反转前:[");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                System.out.println(arr[i] + "]");
            } else {
                System.out.print(arr[i] + ", ");
            }
        }

        //进行数组的反转
        /*for (int start = 0 , end = arr.length - 1 ; start < end ; start++ , end--) {
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }*/

        /*for (int i = 0; i < arr.length - 1 - i ; i++) {
            int temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }*/

        for (int i = 0; i < arr.length / 2 ; i++) {
            int temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }


        //进行数组反转后的打印
        System.out.print("反转后:[");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                System.out.println(arr[i] + "]");
            } else {
                System.out.print(arr[i] + ", ");
            }
        }
    }
}

冒泡排序

原理:比较两个相邻的元素,将值大的元素交换至右端

  • 内外层循环的意义:
    • 外层循环表示求最大值的次数(int count=1;count<arr.length-1;count++)
    • 内层循环表示求一次最大值需要比较几次(int i=0;i<arr.length-i;i++)

图解
1391679-20180618163321525-1936669878.gif

public class ArrayDemo06 {
    public static void main(String[] args) {
        //声明初始化数组
        int[] arr = {4,3,2,1};

        //进行数组排序前的打印
        System.out.print("排序前:[");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                System.out.println(arr[i] + "]");
            } else {
                System.out.print(arr[i] + ", ");
            }
        }

        /*
            第一轮第一次比较
                比较前:[4,3,2,1]
                比较后:[3,4,2,1]

        if (arr[0] > arr[0 + 1]) {
            int temp = arr[0];
            arr[0] = arr[0 + 1];
            arr[0 + 1] = temp;
        }


            第一轮第二次比较
                比较前:[3,4,2,1]
                比较后:[3,2,4,1]

         if (arr[1] > arr[1 + 1]) {
             int temp = arr[1];
             arr[1] = arr[1 + 1];
             arr[1 + 1] = temp;
         }

         /*
            第一轮第三次比较
                比较前:[3,2,4,1]
                比较后:[3,2,1,4]

         if (arr[2] > arr[2 + 1]) {
             int temp = arr[2];
             arr[2] = arr[2 + 1];
             arr[2 + 1] = temp;
         }
         */

         /*
            第一轮比较
                 比较前:[4,3,2,1]
                 比较后:[3,2,1,4]

        for (int i = 0; i < arr.length - 1 ; i++) {
            if (arr[i] > arr[i+1]) {
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }

        /*
            第二轮比较
                 比较前:[3,2,1,4]
                 比较后:[2,1,3,4]

        for (int i = 0; i < arr.length - 2 ; i++) {
            if (arr[i] > arr[i+1]) {
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }

        /*
            第三轮比较
                 比较前:[2,1,3,4]
                 比较后:[1,2,3,4]

        for (int i = 0; i < arr.length - 3 ; i++) {
            if (arr[i] > arr[i+1]) {
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        */

        //外层循环:求几次最大值       内层循环:求1次最大值需要比较几次
        for (int count = 1 ; count < arr.length ; count++) {
            for (int i = 0 ; i < arr.length - count ; i++) {
                if (arr[i] > arr[i+1]) {
                    int temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                }
            }
        }


        //进行数组排序后的打印
        System.out.print("排序后:[");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                System.out.println(arr[i] + "]");
            } else {
                System.out.print(arr[i] + ", ");
            }
        }
    }
}
  • 获取指定元素在数组中出现的第一次索引
public class ArrayDemo07 {
    public static void main(String[] args) {
        //声明初始化数组
        int[] arr = {2,5,7,8,10,15,18,20,22,25,28};

        //声明初始化指定元素
        int num = 18;

        //声明初始化索引变量
        int index = -1;

        for (int i = 0; i < arr.length; i++) {
            if (num == arr[i]) {
                index = i;
                System.out.println("index = " + index);
                break;
            }
        }

        if (index == -1) {
            System.out.println("无法获取指定元素");
        }
    }
}

  • 二分查找法(折半查找法)

前提条件:

容器必须是有序(数据从小到大或者从大到小)

注意:循环中中间位置索引变成两端的索引后,如何处理两端的索引值(start=mid+1;end=mid-1)

方法图解

image-20211221232918370

public class ArrayDemo08 {
    public static void main(String[] args) {
        //声明初始化数组
        int[] arr = {2,5,7,8,10,15,18,20,22,25,28};

        //声明初始化指定元素
        int num = 18;

        //声明初始化索引变量
        int index = -1;

        //声明初始化待查找数据的范围索引变量
        int start = 0;
        int end = arr.length - 1;

        //声明初始化中间变量的索引
        int mid = (start + end) / 2;

        //因为不清楚经历多少次循环获取到索引,选择while循环
        while (start <= end) {
            if (arr[mid] < num) {
                start = mid + 1;
                //mid = (start + end) / 2;
            } else if (arr[mid] > num) {
                end = mid - 1;
                //mid = (start + end) / 2;
            } else {
                index = mid;
                break;
            }

            mid = (start + end) / 2;
        }

        if (index == -1) {
            System.out.println("无法获取指定元素");
        } else {
            System.out.println("index = " + index);
        }
    }
}

  • 数组的动态扩容,删除,插入

动态删除图解

image-20211222000154360

public class ArrayDemo09 {
    public static void main(String[] args) {
        //声明初始化数组
        int[] arr = {11,22,33};
        System.out.println("添加前:" + printArr(arr));
        arr = add(arr,44);
        System.out.println("添加后:" + printArr(arr));
        System.out.println("============================================");
        System.out.println("删除前:" + printArr(arr));
        arr = remove(arr,3);
        System.out.println("删除后:" + printArr(arr));
        System.out.println("============================================");
        System.out.println("插入前:" + printArr(arr));
        arr = insert(arr,2 , 55);
        System.out.println("插入后:" + printArr(arr));
    }

    /*
        数组的动态插入
        两个明确:
            返回值类型: int[]
            形参列表:int[] oldArr, int index , int num
    */
    public static int[] insert (int[] oldArr, int index , int num) {
        //考虑数组的长度不能改变,需要根据原来的数组创建长度+1的数组
        int[] newArr = new int[oldArr.length + 1];

        //将原数组中的数据依次复制到新数组中
        for (int i = 0; i < oldArr.length; i++) {
            if (i < index) {
                //等位置移动
                newArr[i] = oldArr[i];
            } else {
                //错位移动
                newArr[i + 1] = oldArr[i];
            }
        }

        //将指定元素存储到新数组中的指定索引处
        newArr[index] = num;

        //返回新数组
        return newArr;
    }

    /*
        数组的动态删除
        两个明确:
            返回值类型: int[]
            形参列表: int[] oldArr , int index
    */
    public static int[] remove (int[] oldArr , int index) {
        //考虑数组的长度不能改变,需要根据原来的数组创建长度-1的数组
        int[] newArr = new int[oldArr.length - 1];

        //将原数组中的数据依次复制到新数组中
        for (int i = 0; i < newArr.length; i++) {
            if (i < index) {
                //等位置移动
                newArr[i] = oldArr[i];
            } else {
                //错位移动
                newArr[i] = oldArr[i+1];
            }
        }

        //返回新数组
        return newArr;
    }


    /*
        数组的动态扩容
        两个明确:
            返回值类型: int[]
            形参列表: int[] oldArr, int num
    */
    public static int[] add (int[] oldArr , int num) {
        //考虑数组的长度不能改变,需要根据原来的数组创建长度+1的数组
        int[] newArr = new int[oldArr.length + 1];

        //将原数组中的数据依次复制到新数组中
        for (int i = 0; i < oldArr.length; i++) {
            newArr[i] = oldArr[i];
        }

        //需要将待添加元素存储到新数组最后一个位置
        newArr[newArr.length - 1] = num;

        //返回新数组
        return newArr;
    }


    public static String printArr (int[] arr) {
        String s = "[";

        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                s += arr[i] + "]"; //s = s + arr[i] +  "]";
            } else {
                s += arr[i] + ", ";// s = s + arr[i] + ", "
            }
        }

        return s;
    }
}

ps:在给新数组元素赋值时,注意索引 (i<?) 的范围,用newArr.length还是oldArr.length

  • 合法性校验
public class ArrayDemo10 {
    public static void main(String[] args) {
        int[] arr = {11,22,33};
        int num = getNum(arr , 10);
        System.out.println("num = " + num);
    }

    /*
        两个明确:
            返回值类型: int
            形参列表: int[] arr , int index
    */
    public static int getNum (int[] arr, int index) {
        if (arr == null) {
            return 0;
        }

        if (index < 0 || index >= arr.length) {
            System.out.println("索引非法");
            return 0;
        }

        int num = arr[index];
        return num;
    }
}

二维数组

定义:就是数组中的元素数据类型还是数组结构的数组

/**
 * 二维数组:
 *      就是数组中的元素数据类型还是数组结构的数组
 *
 * 二维数组的声明
 *      数据类型[][] 数组名;(推荐)
 *      数据类型 数组名[][];
 *      数据类型[] 数组名[];
 *
 * 二维数组的初始化
 *      动态初始化:
 *          格式1:初始化二维数组,同时也初始化里面的一维数组
 *              数据类型[][] 数组名 = new 数据类型[m][n];
 *              m : 二维数组的长度 或者 在二维数组中存在几个一维数组
 *              n : 每个一维数组中含有多少个元素
 *          格式2:只初始化二维数组,不初始化里面的一维数组
 *              数据类型[][] 数组名 = new 数据类型[m][];
 *      静态初始化:
 *          格式1:标准版
 *              数据类型[][] 数组名 = new 数据类型[][]{new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}};
 *          格式2:半简化版
 *              数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}};
 *          格式3:简化版
 *              数据类型[][] 数组名 = {{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}};
 */
public class ArrayDemo11 {
    public static void main(String[] args) {
        //数据类型[][] 数组名;
        int[][] arr01;
        //数据类型 数组名[][];
        int arr02[][];
        //数据类型[] 数组名[];
        int[] arr03[];
        //数据类型[][] 数组名 = new 数据类型[m][n];
        int[][] arr04 = new int[3][2]; // {{0,0},{0,0},{0,0}}
        System.out.println(arr04);
        System.out.println(arr04[0]);
        System.out.println(arr04[0][0]);
        System.out.println(arr04[0][1]);
        System.out.println(arr04[1]);
        System.out.println(arr04[2]);
        //数据类型[][] 数组名 = new 数据类型[m][];
        int[][] arr05 = new int[3][];
        System.out.println(arr05);
        System.out.println(arr05[0]);
        System.out.println(arr05[1]);
        System.out.println(arr05[2]);
        //数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}};
        int[][] arr06 = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
        //数据类型[][] 数组名 = {{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}};
        int[][] arr07 = {{1,2,3},{4,5},{6,7,8,9}};
    }
}

二维数组的遍历

  • 外层循环:i<arr.length
  • 内层循环:j<arr[i].length
public class ArrayDemo12 {
    public static void main(String[] args) {
        //声明初始化二维数组
        int[][] arr = {{1,2,3},{4,5},{6,7,8,9}};
        System.out.println(arr);
        System.out.println(arr[0]);
        System.out.println(arr[0][0]);
        System.out.println(arr[0][1]);
        System.out.println(arr[0][2]);
        System.out.println(arr[1]);
        System.out.println(arr[1][0]);
        System.out.println(arr[1][1]);
        System.out.println(arr[2]);
        System.out.println(arr[2][0]);
        System.out.println(arr[2][1]);
        System.out.println(arr[2][2]);
        System.out.println(arr[2][3]);

        System.out.println("=======================");

        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.println(arr[i][j]);
            }
        }
    }
}

二维数组的内存图解

image-20220212003350991

二维数组初始化及方法出栈后的内存图解:若主方法结束,则0x666不指向栈了,此时0x6661,0x6662,0x6663三个指向还在,那么0x666被认定为垃圾数据,等待扫描.清理,此时三个指向没了,各自被认定为立即数据,等待清理回收.(二维数组驻留内存较长,开发中不常用)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值