day 05 数组学习

第5章 数组学习

目录

  • 数组

  • 排序

  • 查找

  • 多维数组

数组

数组的必要性

前言

  • 导入

    题干:养鸡场有6只鸡,它们的体重分别是3kg,5kg,1kg,3.4kg,2kg,50kg。六只鸡的总体重?平均体重是多少?Array01.java

    传统思路:定义6个变量,加起来总体重,求出平均值

    引入新知识:数组

  • 介绍

    数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。即:数组就是一组数据

  • 快速入门Array01.java

            /*解读
            1. double[] 表示double类型的数组 hens 数组名
            2. { }表示数组的值/元素,依次表示数组的第几个元素
             */
            double[] hens = {3,5,1,3.4,2,50};
    
            /*遍历数组得到数组的所有元素的和,使用for循环
            1.我们可以通过hens[下标]来访问数组的元素
            2.下标从0开始编号 比如第一号元素就是 hens[0] 第二个元素就是hen[1] 依次类推
            3.通过for就可以循环的访问数组的元素/值
            3.使用一个变量 total 蒋个元素累积
            */
            double totalWeight = 0;
    
            //提示:可以通过 数组名.length 得到数组的大小/长度
            //System.out.println("数组长度=" + hens.length);
    
            for (int i = 0; i < hens.length; i++) {
                //System.out.println("第" + (i + 1) +"个元素的值=" + hens[i]);
                totalWeight += hens[i];
            }
            System.out.println("总体重=" + totalWeight
                    + "平均体重=" + (totalWeight / hens.length));
    
    

使用方式

  • 使用方式1-动态初始化

    数组的定义

    //数据类型 数组名[] = new 数据类型 [大小]
    int[] a = {} == int a[] = {};
    int a[ ] = new int[5];//创建了一个数组,名字a,存放5个int
    

    数组的引用(使用/访问)

    数组名[下标/索引]
    //比如:要使用a数组的第3个数 a[2]
    

    快速入门Array02.java

    //循环输入5个成绩,保存到double数组,并输出
    package chapter06.array;
    import java.util.Scanner;
    public class Array02 {
        public static void main(String[] args) {
    
            //1.创建double数组,数组大小5
            double score[] = new double[5];
            //2.循环输入
            Scanner scanner = new Scanner(System.in);
            for (int i = 0; i < score.length; i++) {
                System.out.println("请输入第"+ (i + 1) +"个元素的值");
                score[i] = scanner.nextDouble();
            }
            //3.循环输出 遍历数组
            for (int i = 0; i < score.length; i++) {
                System.out.println("第"+ (i + 1) +"个元素的值=" + score[i]);
            }
    
        }
    }
    
  • 使用方式2-动态初始化

    声明数组

    //语法:数据类型 数组名[];or数据类型[] 数组名;
    int a[];
    int[] a;
    

    创建数组

    //语法:数组名 = new 数据类型[大小]; 
    a = new int[10];
    

    案例演示(前面修改)

     //1.先声明数组,此时 a 是 null
            int a[];
            //2.new一个分配内存空间,可以存放数据
            a = new int[3];
    
  • 使用方式3-静态初始化

    初始化数组

    //语法:数据类型 数组名[] = {元素值元素值...}
    int a[] ={2,5,6,7,8,89,90,34,56};//如果知道数组有多少元素,具体值上面的用法相当于如下
    int a[] = new int[9];
    /*
    a[0] = 2; a[1] = 5; a[2] = 6; a[3] = 7; 
    a[4] = 8; a[5] = 89; a[6] = 90; a[7] = 34; a[8] = 56;
    */
    

    快速入门案例(养鸡场Array01.java)

    double hens[] = {3, 5, 1, 3.4, 2, 50};
    //等价
    double hens[] = new double[6];
    hens[0] = 3; hens[1] = 5; hens[2] = 1; hens[3] = 3.4; hens[4] = 2; hens[5] = 50
    

注意事项

  • ArrayDetail.java

    1.数组是多个相同类型数据的组合,实现对这些数据的统一管理

    2.数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用

    3.数组创建后如果没有赋值有默认值int 0,short 0,byte 0,long 0,float 0.0,double 0.0,char \u0000,boolean false,String null

    4.使用数组的步骤 1.声明数组并开辟空间 2.给数组各个元素赋值 3.使用数组

    5.数组的下标是从0开始的

    6.数组下标必须在指定范围内使用,否则报下标越界异常,比如int [] array = new int[5];则有效下标为0-4

    7.数组属引用类型,数组型数据是对象(object)

练习题

  • ArrayExercise01.java

    1.创建一个char类型的26个元素的数组,分别放置’A’-‘Z’。使用for循环访问所有元素并打印出来。
    提示:char类型数据运算’A’+ 1 -->‘B’

    package chapter06.array;
    public class ArrayExercise01 {
        public static void main(String[] args) {
            //创建一个char类型的26个元素的数组,分别放置'A'-'Z'。使用for循环访问所有元素并打印出来。
            /*
            1.定义一个数组 char[] chars = new char[26]
            2.因为'A' + 1 = 'B' 类推,所以老师使用for来赋值
            3.使用for循环来访问所有元素
             */
    
            char[] chars = new char[26];
            for ( int i =0; i < chars.length; i++) {//循环26次
                chars[i] = (char)('A' + i);//'A' + i是int-->char要强转
            }
            //循环输出
            for ( int i =0; i < chars.length; i++) {//循环26次
                System.out.println(chars[i]);
            }
    
        }
    }
    
  • ArrayExercise02.java

    2.请求出一个数组int[ ]的最大值{4,-1,9,10,23},并得到对应的下标。(内存分析法)

    package chapter06.array;
    
    public class ArrayExercise02 {
        public static void main(String[] args) {
            //请求出一个数组int[ ]的最大值{4,-1,9,10,23},并得到对应的下标。
            /*
            1.定义一个数组 int[] arr = {4,-1,9,10,23}
            2.假定max arr[0] 是最大值 ,maxIndex = 0;
            3.从下标 1 开始遍历arr ,如果 max < 当前元素 ,说明max 不是真正的最大值
            我们就把 max = 当前元素; maxIndex = 当前元素下标
            4.当遍历完整个数组ARR之后,max就是真正的最大值,maxIndex最大值
             */
            int arr[] = {4,-1,9,10,23};
            int max = arr[0];//假定一个元素就是最大值
            int maxIndex = 0;
            for (int i = 1; i < arr.length; i++) {
                if (max < arr[i]) {//如果max < 当前元素
                    max = arr[i];//重新赋值 max
                    maxIndex = i;//重新赋值 maxIndex
                }
            }
            //当遍历完整个数组后,max就是真正的最大值,maxIndex也是最大值下标
            System.out.println("最大值=" + max + " 最大值下标=" + maxIndex);
        }
    
    }
    
  • ArrayExercise03.java

    3.请求出一个数组的和以及平均值。(养鸡场)

数组赋值机制

值拷贝和地址拷贝

  1. 基本数据类型赋值(分配),这个值就是具体的数据,而且相互不影响。

    int n1 = 2; int n2 = n1;
    
  2. 数组在默认情况下是引用传递,赋的值是地址。看一个案例,并分析数组赋值的内存图* ArrayAssign.java

    int[] arr1 = {1,2,3};
    int[] arr2 = arr1;
    
    package chapter06.array;
    
    public class ArrayAssign {
        public static void main(String[] args) {
            //基本数据类型,赋值方式为值拷贝即值传递
            //n2的变化不会影响到n1的值
            int n1 = 10;
            int n2 = n1;
            n2 = 80;
            System.out.println("n1=" + n1);//10
            System.out.println("n2=" + n2);//80
    
            //数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用传递是一个地址
            int[] arr1 = {1,2,3};
            int[] arr2 = arr1;//把arr1赋给 arr2 ,arr2的变化会影响到arr1
            arr2[0] = 10;
            //看看Arr1的值
            for (int i = 0; i < arr1.length; i++) {
                System.out.println(arr1[i]);//10,2,3
            }
            //看看Arr2的值
            for (int i = 0; i < arr2.length; i++) {
                System.out.println(arr1[i]);//10,2,3
            }
            
        }
    }
    
  3. 内存分析图**-重要!!!**

    在这里插入图片描述

数组拷贝

  1. 编写代码实现数组拷贝(内容复制)ArrayCopy.java
    要求:将int[] arr1 = {10,20,30}; 拷贝到arr2数组中,要求数据空间独立

    package chapter06.array;
    
    public class ArrayCopy {
        public static void main(String[] args) {
    
            int[] arr1 = {10,20,30};
    
            //创建一个新的数组arr2,开辟新的数据空间
            //空间大小保证和arr1.length一样大;
            int[] arr2 = new int[arr1.length];
    
            //遍历Arr1 ,把每个元素拷贝到arr2对应的元素位置
            for (int i = 0; i < arr1.length; i++) {
                arr2[i] = arr1[i];
            }
    
            //修改Arr2,不会对Arr1产生影响
            arr2[0] = 100;
    
            //输出arr1
            System.out.println("=====arr1的元素=====");
            for (int i = 0; i < arr1.length; i++) {
                System.out.println(arr1[i]);//10,20,30修改不会影响arr1的值
            }
            //输出arr2
            System.out.println("=====arr2的元素=====");
            for (int i = 0; i < arr1.length; i++) {
                System.out.println(arr2[i]);//100,20,30修改不会影响arr1的值
            }
    
        }
    }
    
  2. 内存分析图

    在这里插入图片描述

数组反转(翻转)

  1. 要求:把数组的元素内容反转。ArrayReverse.java

    //arr {11,22,33,44,55,66} --> {66,55,44,33,22,11}
    

    思考:
    方式1通过找规律反转(思路分析)

    package chapter06.array;
    public class ArrayReverse {
        public static void main(String[] args) {
            //定义数组
            int[] arr = {11,22,33,44,55,66};
            //思路分析
            /*
            1.把arr[0]和arr[5]进行交换 {66,22,33,44,55,11}
            2.把arr[1]和arr[4]进行交换 {66,55,33,44,22,11}
            3.把arr[2]和arr[3]进行交换 {66,55,44,33,22,11}
            4.一共交换3次 = arr.length / 2
            5.每次交换时,对应下标是 arr[i] 和 arr[arr.length - 1 - i]
             */
            /*
            优化
            int temp = 0;
            int len = arr.length;
             */
            for (int i = 0; i < arr.length / 2; i++) {
                int temp = arr[arr.length - 1 - i];//引入临时变量保存
                arr[arr.length - 1 - i] = arr[i];//eg:杯子换水
                arr[i] = temp;
            }
    
            System.out.println("====反转数组=====");
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i] + "\t");//66,55,44,33,22,11
            }
    
        }
    }
    

    方式2使用逆序赋值方式(思路分析,自己完成)

     package chapter06.array;
        public class ArrayReverse02 {
            public static void main(String[] args) {
    
            //定义数组
            int[] arr = {11,22,33,44,55,66};
    
            /*
            使用逆序赋值方式
            1.先创建一个新的数组arr2 ,大小arr.length
            2.逆序遍历arr ,将每个元素拷贝到arr2的元素中(顺序拷贝)
            3.建议增加一个循环变量 j == 0-->5
             */
            //创建变量
            int[] arr2 = new int[arr.length];
            //逆序遍历arr
            for (int i = arr.length - 1, j = 0;i >= 0; i--, j++) {
                arr2[j] = arr[i];//j就是代表着 arr.length - 1 - i就是要她从0开始
            }
            //4当for 循环结束, arr2 就是一个逆序的数组{66, 55, 44,33, 22, 11}
            
            //5.让arr 指向 arr2 数据空间,此时arr原来的数据空间就没有变量使用
            arr = arr2;
    
            //6.输出arr看看
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i] + "\t");
            }
            
        }
    }
    

数组添加(扩容)

  • 要求:实现动态的给数组添加元素效果,实现对数组扩容。ArrayAdd.java
    1.原始数组使用静态分配int[] arr = {1,2,3}
    2.增加的元素4,直接放在数组的最后arr = {1,2,3,4}

       package chapter06.array;
        
        public class ArrayAdd {
            public static void main(String[] args) {
                /*
                1.原始数组使用静态分配int[] arr = {1,2,3}
                2.增加的元素4,直接放在数组的最后arr = {1,2,3,4}
                3.用户可以通过如下方法来决定是否继续添加,添加成功,是否继续? y/n
                分析:
                1.定义初始数组 int[] arr = {1,2,3}
                2.//arr[3] = 4;不行,下标越界
                2.定义一个新数组 int[] arrNew = new int[arr.length + 1]
                3.遍历 arr 数组依次将arr的元素拷贝到 arrNew数组中
                4.将 4 赋给arrNew[arrNew.length - 1] = 4;把4赋给arrNew最后一个元素
                5.让arr 指向 arrNew ; arr = arrNew;那么原来的arr就被销毁
                 */
                int[] arr = {1,2,3};
                int[] arrNew = new int[arr.length + 1];
                //遍历 arr 数组,依次将arr 的元素拷贝到 arrNew数组
                for (int i = 0; i < arr.length; i++) {
                    arrNew[i] = arr[i];
                }
                //把4赋给arrNew最后一个元素
                arrNew[arrNew.length - 1] = 4;
                //让arr 指向 arrNew
                arr = arrNew;
                //输出arr 看看效果
                for (int i = 0; i < arr.length; i++) {
                    System.out.println(arr[i]);
                }
        
        
            }
        }
    

    3.用户可以通过如下方法来决定是否继续添加,添加成功,是否继续? y/n

    package chapter06.array;
    
    import java.util.Scanner;
    
    public class ArrayAdd02 {
        public static void main(String[] args) {
    
            /*分析:
            1.定义初始数组 int[] arr = {1,2,3}
            2.//arr[3] = 4;不行,下标越界
            2.定义一个新数组 int[] arrNew = new int[arr.length + 1]
            3.遍历 arr 数组依次将arr的元素拷贝到 arrNew数组中
            4.将 4 赋给arrNew[arrNew.length - 1] = 4;把4赋给arrNew最后一个元素
            5.让arr 指向 arrNew ; arr = arrNew;那么原来的arr就被销毁
            6.创建一个Scanner接受用户输入
            7.因为用户什么时候退出不确定,可以使用do-while + break来控制
            */
            Scanner scanner = new Scanner(System.in);
            int[] arr = {1, 2, 3};
    
            do {
                int[] arrNew = new int[arr.length + 1];//增加数组长度
                //遍历 arr 数组,依次将arr 的元素拷贝到 arrNew数组
                for (int i = 0; i < arr.length; i++) {
                    arrNew[i] = arr[i];
                }
                System.out.println("请输入你要添加的元素");
                int addNum = scanner.nextInt();
                //把addNum赋给arrNew最后一个元素
                arrNew[arrNew.length - 1] = addNum;
                //让arr 指向 arrNew
                arr = arrNew;
                //输出arr 看看效果
                System.out.println("====扩容后的元素情况====");
                for (int i = 0; i < arr.length; i++) {
                    System.out.println(arr[i]);
                }
                //问用户是否继续
                System.out.println("是否继续添加 y/n");
                char key = scanner.next().charAt(0);
                if (key == 'n') {
                    break;//n就结束
                }
    
            }while (true);//该处是死循环 跳出循环就需要在循环体内加条件跳出循环
            System.out.println("你已退出添加");
            
        }
    }
    
  • 课后练习题:ArrayReduce.java
    1.有一个数组{1, 2, 3, 4, 5}, 可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后那个元素。
    2.当只剩下最后个元素,提示,不能再缩减。

    package chapter06.array;
    
    import java.util.Scanner;
    
    public class ArrayReduce {
        public static void main(String[] args) {
            /*
            1.有一个数组{1, 2, 3, 4, 5},可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后那个元素。
            2.当只剩下最后个元素,提示,不能再缩减。
             */
            int[] arr = {1,2,3,4,5};//初始化数组
            Scanner scanner = new Scanner(System.in);//创建一个用户接收
            do {
                int[] arrNew = new int[arr.length - 1];//定义一个新数组,长度比原来的数组减1
    
                for (int i = 0; i < arr.length - 1; i++) {//遍历原数组的前面的元素
                    arrNew[i] = arr[i];//将值赋给新数组
                }
    
                arr = arrNew;//将新的地址指向arr
    
                System.out.println("删减后元素情况");
                for (int i = 0; i < arr.length; i++) {
                        System.out.print(arr[i] + "\t");
                }
    
                System.out.println("是否继续删除 y/n");
                char key = scanner.next().charAt(0);
                if (arr.length == 1) {//判断是否只剩最后1个元素
                    System.out.println("数组只有一个元素,不能继续删减");
                    break;
                }
                if (key == 'n') {//不继续删减
                    break;
                }
    
            } while (true);
    
            System.out.println("你已退出操作");
        }
    }
    

排序

排序介绍

  • 排序定义:排序是将多个数据, 依指定的顺序进行排列的过程。
  • 排序的分类
    1.内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法和插入式排序法);
    2.外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。

冒泡排序(Bubble Sorting)

  • 冒泡排序的基本思想:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒。

  • 冒泡排序法案例BubbleSort.java
    要求:将五个无序数:24,69,80,57,13使用冒泡排序法将其排成一个从小到大的有序数列。

  • 示意图

    在这里插入图片描述

  • 代码实现

    package chapter06.array;
    public class BubbleSort {
        public static void main(String[] args) {
            /*
            化繁为简、先死后活
            1.先完成第一轮,再完成第二轮,再完成第三轮,再找规律
            2.将多轮排序使用一个外层循环包括起来即可
            3.先死后活,再将4改成数组长度 - 1
            */
    
            int[] arr = {24, 69, 80, 57, 13};
            int temp = 0;//辅助交换时的临时变量
    
            //将多轮排序使用一个外层循环包括起来即可
            for ( int i = 0; i < arr.length -1; i++) {//外层循环4次
            //for ( int i = 0; i < 4; i++) {//外层循环4次-->arr.length -1
    
                for (int j = 0; j < arr.length -1 - i; j++) {//第1轮的4次比较-->3-->2-->1
                //for (int j = 0; j < 4 - i; j++) {//第1轮的4次比较-->3-->2-->1---->arr.length -1 -i
                    if (arr[j] > arr[j + 1]) {
                        //如果前面的数大于后面的数,就交换,此处需要临时变量
                        temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
                System.out.println("\n===第"+ (i + 1) +"轮===");
                for (int j = 0; j < arr.length; j++) {
                    System.out.print(arr[j] + "\t");
                }
    
            }
            /*
            for (int j = 0; j < 4; j++) {//第1轮的4次比较
                if (arr[j] > arr[j + 1]) {
                //如果前面的数大于后面的数,就交换,此处需要临时变量
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            System.out.println("\n===第一轮===");
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[j] + "\t");
            }
    
            for (int j = 0; j < 3; j++) {//3次比较
                //如果前面的数大于后面的数,就交换,此处需要临时变量
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            System.out.println("\n===第二轮===");
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[j] + "\t");
            }
            */
        }
    }
    

查找

介绍

  • java中常用的2种查找方式
    1.顺序查找SeqSearch.java
    2.二分查找(二分法,放在算法中讲)

  • 案例演示
    1.顺序查找:有一个数列白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王进行猜数,从键盘中任意输入一个名称,判断数列中是否包含此名称。要求:如果找到了,就提示找到,并给出下标值。

    package chapter06.array;
    
    import java.util.Scanner;
    
    public class SeqSearch {
        public static void main(String[] args) {
            /*
            1.定义一个字符串数组
            2.接受用户输入,遍历数组,逐一比较,如果有,就提示信息并退出
             */
            String[] name = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"};
            Scanner scanner = new Scanner(System.in);
    
            System.out.println("请输入名字");
            String findName = scanner.next();
    
            //这里给一个编程思想/技巧 ,一种经典方法
            int index = -1;//初始化不能为0-3,其他数都可以
            //遍历数组,逐一比较
            for (int i = 0; i < name.length; i++) {
                //字符串比较 equals,如果要找名字就是当前元素
                if (findName.equals(name[i])) {//提示最好用name[i].equals(findName);避免空指针异常
                    System.out.println("恭喜找到" + findName);
                    System.out.println("下标为" + i);
                    //把 i 保存到 index
                    index = i;
                    break;//找到后退出,但是如果第一个不是就直接跳出会导致后面的元素无法被遍历
                }
            }
            if (index == -1) {
                //如果 index = -1证明上述 for循环没有进入到 if语句块中
                System.out.println("您输入的名字没有在所属数列中");
            }
            
        }
    }
    
  • 2.请对一个有序数组进行二分查找{1,8, 10, 89, 1000, 1234},输入一个数看该数组中是否存在此数,并且求出下标,如果没有就提示"没有这个数"。

多维数组

二维数组前言

  • 多维数组我们只介绍二维数组。

  • 二维数组的应用场景:
    比如我们开发一个五子棋游戏, 棋盘就是需要二维数组来表示。如图:

    在这里插入图片描述

  • 快速入门案例TwoDimensionalArray01.java
    请用二维数组输出如下图形
    0 0 0 0 0 0
    0 0 1 0 0 0
    0 2 0 3 0 0
    0 0 0 0 0 0

    package chapter06.array;
    public class TwoDimensionalArray01 {
        public static void main(String[] args) {
            /*
            请用二维数组输出如下图形
            0 0 0 0 0 0
            0 0 1 0 0 0
            0 2 0 3 0 0
            0 0 0 0 0 0
            1.从定义形式上看int[ ][ ]
            2.可以理解为原来的一维数组的每个元素是一维数组,就构成二维数组
            3.第一个[]表示二维数组里有几个一维数组,第二个[]表示每个一维数组的下标,这样好理解一点点
             */
            int[][] arr = {{0, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0},
                    {0, 2, 0, 3, 0, 0}, {0, 0, 0, 0, 0, 0} };
    
            //输出二维图形
            //1.遍历完二维数组的每个元素(数组)
            //2.arr.length 表示有几个一维数组
            for (int i = 0; i < arr.length; i++) {
                //1.arr[i] 表示二维数组的第 i+1个元素(一维数组),比如arr[0]
                //2.arr[i].length 得到对应 i个元素(一维数组)的长度
                for (int j = 0; j < arr[i].length; j++) {
                    System.out.print(arr[i][j] + " ");//输出一维数组
                }
                System.out.println();//换行
            }
    
        }
    }
    

    //关于二维数组的关键概念

    1.二维数组的元素个数只有四个,即{xxx},{xxx},{xxx},{xxx}

    System.out.println("二维数组的元素个数=" + arr.length);
    

    2.二维数组的每个元素是一个一维数组,所以如果需要得到每个一维数组的值还需要再次遍历

    3.要访问第 i + 1 个一维数组的第 j + 1个值 arr[i] [j]–>arr[2] [3] 代表第3个元素的第4个值

    System.out.println("第3个一维数组的第4个值=" + arr[2][3]);
    

二维数组的使用

使用方式1:动态初始化

  • TwoDimensionalArray02.java
    1.语法:类型[][]数组名 = new 类型 [大小] [大小]
    2.比如: int a[] [] = new int[2] [3];
    3.使用演示

    4.二维数组在内存的存在形式(重点)

  • package chapter06.array;
    
    public class TwoDimensionalArray02 {
        public static void main(String[] args) {
            int arr[][] = new int[2][3];//创建一个 000 000的二维数组
            arr[1][1] = 8;//初始化 最后输出数组应该为 000 080
            //遍历arr数组
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    System.out.print(arr[i][j] + " ");
                }
                System.out.println();//换行
            }
    
        }
    }
    
  • 二维数组内存分析图

    在这里插入图片描述

使用方式2:动态初始化

  • TwoDimensionalArray02.java

  • 1.先声明:类型 数组名[] [];
    2.再定义 (开辟空间)数组名 = new 类型[大小] [大小]
    3.赋值(有默认值,比如int类型的就是0)
    4.使用演示

  • //int arr[][] = new int[2][3];
    int arr[][]; //声明二维数组
    arr = new int[2][3];//再开空间
    

使用方式3:动态初始化-列数不确定

  • TwoDimensionalArray03.java

  • 1.看一个需求:动态创建下面二维数组,并输出。
    在这里插入图片描述

    2.完成该案例
    3.画出执行分析示意图

  • package chapter06.array;
    public class TwoDimensionalArray03 {
        public static void main(String[] args) {
            /*
            int[3][] = { {1}, {2,2}, {3,3,3} };
            1.一共有三个一维数组,每个一个数组的元素是不一样的
             */
            int[][] arr = new int[3][];//创建二维数组,但只是确定一维数组的个数-3(而没有给一维数组开空间)
            for (int i = 0; i  < arr.length; i++) {//遍历arr的每个一维数组
                //给每个一维数组开空间 new
                //如果没有给一维数组 new ,那么arr[i]就是 null
                arr[i] = new int[i + 1];
    
                //遍历一维数组,并给一维数组的每个元素赋值
                for (int j = 0; j < arr[i].length; j++) {
                    arr[i][j] = i + 1;
                }
            }
            //遍历arr输出
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    System.out.print(arr[i][j] + " ");
                }
                System.out.println();//换行
            }
            
        }
    }
    

使用方式4:静态初始化

  • 1.定义:类型 数组名[] [] = { {值1,值2…},{值1,值2…},{值1,值2…} }
    2.使用即可(固定方式访问)

    比如:int[] [] arr = {{1,1,1}, {8,8,9},{100}};//即使最后一个一维数组只有1个元素,也要用{}包括,不能用{{1,1,1}, {8,8,9}, 100}表示,因为100是int基本数据类型,而不是int[]这种引用类型
    
  • 解读
    1.定义了一个二维数组
    2.arr有三个元素(每个元素都是一维数组)
    3.第一个一维数组有3个元素,第二个一维数组有3个元素,第三个一维数组有1个元素

使用方式练习题

  • TwoDimensionalArray05.java

  • package chapter06.array;
    
    public class TwoDimensionalArray05 {
        public static void main(String[] args) {
            //int arr[][]={{4,6},{1,4,5,7},{-2}}; 遍历该二维数组,并得到和
            //思路
            //1.遍历二维数组,,并将各个值累计到int sum
            int arr[][] = { {4,6}, {1,4,5,7}, {-2} };
            int sum = 0;
            for (int i = 0; i < arr.length; i++) {
                //遍历每个一维数组
                for (int j = 0; j < arr[i].length; j++) {
                    sum += arr[i][j];
                }
            }
            System.out.println("输出的二维数组值为=" + sum);
    
        }
    }
    

二维数组使用细节和注意事项

  1. 一维数组的声明方式有:int[] x或者int x[]

  2. 二维数组的声明方式有:int[] [] y或者**int[] y[]**或者int y[] []

  3. 二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。

    比如:map[][] 是一个二维数组map[] [] = { {1,2}, {3,4,5} } ,由map[0]是一个含有2个元素的一维数组,map[1] 是一个含有3个元素的一维数组构成,我们也称为列数不等的二维数组。

练习题

  • 声明:int[] x,y[]; 以下选项允许通过编译的是()

    a) x[0] = y;//错误 二维不能赋给一维
    b) y[0] = x;//正确 一维数组可以赋给一维数组 x-->y[0] (本质就是一个一维数组)
    c) y[0][0] = x;//错误 一维数组不能赋给一个具体的int值
    d) x[0][0] = y;//错误 x是一维数组
    e) y[0][0] = x[0];//正确 一个int可以赋给一个int
    f) x = y;//错误 二维不能赋给一维
    
  • 解答://x是int类型的一维数组 int[] x
    //y是int类型的二维数组,int[] y[]

杨辉三角

  • 1.使用二维数组打印一个10行杨辉三角YangHui.java
    1
    1 1
    1 2 1
    1 3 3 1
    1 4 6 4 1
    1 5 10 10 5 1

  • 提示
    1.第一行有1个元素,第n行有n个元素
    2.每一行的第一个元素和最后一个元素都是1
    3.从第三行开始对于非第个元素和最后个元素的元素的值.arr[i] [j]
    arr[i] [j] = arr[i-1] [j] + arr[i-1] [j-1];//必须找到这个规律才能写出杨辉三角

  • 代码实现

    package chapter06.array;
    
    public class YangHui {
        public static void main(String[] args) {
    
            int[][] arr = new int[10][];//创建一个二维数组,10行但元素不确定
    
            for (int i = 0; i < arr.length; i++) {//遍历arr的每个元素
    
                arr[i] = new int[i + 1];//给每个一维数组开辟空间 new
    
                for (int j = 0; j < arr[i].length; j++) {//遍历输入 给每个一维数组(每行)进行赋值
                    /*这里的赋值有要求
                    1.第一行有1个元素,第n行有n个元素
                    2.每一行的第一个元素和最后一个元素都是1
                    3.从第三行开始对于非第个元素和最后个元素的元素的值.arr[i] [j]
                    arr[i] [j] = arr[i-1][j] + arr[i-1][j-1];//必须找到这个规律才能写出杨辉三角
                     */
                    if (j == 0 || j == arr[i].length - 1) {//这里j == 长度-1 而不等于 i 不然会造成空指针异常
                        arr[i][j] = 1;//给第一个和最后一个元素赋值为1
                    } else {
                        arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];//中间元素赋值
                    }
    
                }
            }
            //输出杨辉三角
            for (int i = 0; i < arr.length; i++) {//遍历输出 换行 
                for (int j = 0; j < arr[i].length; j++) {//我真的会谢 里面的参数是i 不是j 我是傻逼打成j
                    System.out.print(arr[i][j] + " ");
                }
                System.out.println();//换行
            }
    
        }
    }
    

家庭作业

  1. 下面数组定义正确的有Homework01.java

    A.String strs[] = {'a', 'b', 'c'};//错误 类型不兼容 Char-->String
    B.String[] strs = {"a", "b", "c"};//ok 
    C.String[] strs = new String{"a" "b" "c"};//错误 无,
    D.String strs[] = new String[]{"a", "b", "c"};//ok
    E.String[] strs = new String[3]{"a", "b","c"};//错误 编译不通过
    
  2. 写出结果Homework02.java

    String foo = "blue";
    boolean[] bar = new boolean[2];//Boolean默认flase;bar[0]默认flase,bar[1]默认flase
    if(bar[0]){//默认flase,不进入if语句
        foo = "green";
    }
    System.out.println(foo);//blue
    
  3. 以下Java代码的输出结果为Homework03.java

    int num = 1; 
    while(num < 10) {
        System.out.println(num);
        if(num > 5) {
            break;
        }
            num += 2;
    }//1 3 5 7
    
  4. 已知有个升序的数组,要求插入一个元素,该数组顺序依然是升序,比如[10, 12, 45, 90],添加23后,数组为[10, 12, 23, 45, 90]Homework04.java

    //自己是扩容+冒泡(网友提示:不满足要求,因为原题干是插入该元素后仍然是升序排列)

    package chapter06.homework;
    
    public class HomeWork04 {
        public static void main(String[] args) {
            /*
            已知有个升序的数组,要求插入一个元素,该数组顺序依然是升序,
            比如[10, 12, 45, 90],添加23后,数组为[10, 12, 23, 45, 90]
             */
            int[] arr = {10, 12, 45, 90};//创建数组
            int[] arrNew = new int[arr.length + 1];//扩容
            //遍历数组,将arr拷贝到arrNew数组中
            for (int i = 0; i < arr.length; i++) {
                arrNew[i] = arr[i];
            }
            //把新给的值赋给arrNew
            arrNew[arrNew.length - 1] = 23;
            //让arr地址指向 arrNew 将arrNew的地址赋给arr
            arr = arrNew;
            //对arr进行冒泡排序{10, 12, 45, 90, 23}-->{10, 12, 23, 45, 90}
            int temp = 0;//临时变量
            for (int i = 0; i < arr.length - 1; i++) {//遍历输出
                for (int j = 0; j < arr.length - 1 - i; j++) {
                    if (arr[j] < arr[j + 1]) {//引入临时变量
                        continue;
                    }else {
                        temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
                for (int j = 0; j < arr.length; j++) {//遍历输出
                    System.out.print(arr[j] + " ");
                }
                System.out.println();//换行
            }
    
        }
    }
    

    //老师:扩容 + 定位

    package chapter06.homework;
    
    public class HomeWork04_Ture {
        public static void main(String[] args) {
            /*
            思路本质数组定位 + 扩容
            1.我们先确定添加数应该插入到哪个索引
            2.然后扩容
            */
            //先定义原数组
            int[] arr = {10, 12, 45, 90};
            int insertNum = 23;
            int index = -1; //index就是要插入的位置 索引(此处可以直接赋 arr.length的长度给索引)
    
            //遍历arr数组, 如果发现insertNum <= arr[i], 说明i就是要插入的位置
            //使用index 保留 index = i;
            //如果遍历完后,没有发现满足条件insertNum <= arr[i], 说明index = arr.length 添加到最后
            for (int i = 0; i < arr.length; i++) {
                if (insertNum <= arr[i]) {
                    index = i;
                    break;
                }
            }
            //判断index的值
            if (index == -1) {//说明还没有进入for循环
                index = arr.length;
            }
    
            //扩容
            int[] arrNew = new int[arr.length + 1];
            //将arr的元素拷贝到 arrNew ,并且要跳过 index的位置
            /*
            分析:int[] arr = {10, 12, 45, 90}
            arrNew = {10,12, ,45,90}先跳过,然后再把23填到 i = 2的位置
             */
            for (int i = 0, j = 0; i < arrNew.length; i++) {
                if(i != index) {//说明可以把arr的元素拷贝到 arrNew中
                    arrNew[i] = arr[j];//双索引 这里可以对元素进行错位插入
                    j++;//先拷贝在 j++ 可以用内存分析法进行分析(非常巧妙)
                }else {//i 就是要插入的数
                    arrNew[i] = insertNum;
                }
            }
            //让arr 指向 arrNew
            arr = arrNew;
    
            System.out.println("插入后arr数组的元素情况");
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
    
        }
    }
    
  5. 随机生成10个整数(1-100的范围)保存到数组,并倒序打印以及求平均值,求最大值和最大值的下标并查找里面是否有 8 -->Homework05.java

    package chapter06.homework;
    
    public class HomeWork05 {
        public static void main(String[] args) {
            /*
            要求:随机生成10个整数(1-100的范围)保存到数组,并逆序打印以及求平均值,求最大值和最大值的下标并查找里面是否有8
             */
            int[] arr = new int[10];
            //(int)(Math.random() * 100) + 1;生成随机整数 1-100
            for (int i = 0; i < arr.length; i++) {
                arr[i] = (int)(Math.random() * 100) + 1;
            }
            System.out.println("====正序打印====");
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            //倒序打印
            System.out.println("\n====倒序打印====");
            for (int i = arr.length - 1; i >= 0; i--) {
                System.out.print(arr[i] + " ");
            }
    
            double sum = 0;//声明总数
            int max = arr[0]; //假定最大值为第0号元素
            int index = 0;//最大下标为0
            for (int i = 0; i < arr.length; i++) {//此处如果改成了int i = 1; 上方的sum 的初始值应该为arr[0]
                sum += arr[i];//从0号元素开始
                if (max < arr[i]) {
                    max = arr[i];
                    index = i;
                }
            }
            System.out.println("\n最大值为=" + max + " 最大值下标为=" + index);
            System.out.println("平均值为=" + (sum / arr.length));
    
            //查找随机数组中是否含有8 for循环 顺序查找
            int findNum = 8;
            int numIndex = -1;//把下标记录到index中
            for (int i = 0; i < arr.length; i++) {
                if (findNum == arr[i]) {
                    System.out.println("找到数=" + findNum + "下标为=" + i);
                    numIndex = i;
                    break;
                }
            }
            if (numIndex == -1) {
                System.out.println("随机数组中没有" + findNum);
            }
    
    
        }
    }
    
  6. 试写出以下代码的打印结果Homework06.java//数组传递机制

    char[] arr1 = {'a', 'z', 'b', 'c'};
    char[] arr2 = arr1;
    arr1[2] = '韩';
    for(int i = 0; i < arr2.length; i++){
        System.out.println(arr1[i]+ ","+ arr2[i]);
        //画内存分析图
    

    在这里插入图片描述

  7. 写出冒泡排序的代码Homework07.java

    package chapter06.homework;
    
    public class HomeWork07 {
        public static void main(String[] args) {
            int[] arr = {1, 23, 5, 77, 68};
            int temp = 0;//引入临时变量
            for (int i = 0; i < arr.length - 1; i++) {//外层循环 次数等于长度减1
                for (int j = 0; j < arr.length - 1; j++) {// 内存循环 也是次数减1
                    if (arr[i] > arr[i + 1]) {//从小到大顺序的话就大小交换 如果从大到小就将 > 改成 < 
                        temp = arr[i + 1];
                        arr[i + 1] = arr[i];
                        arr[i] = temp;
                    }
                }
            }
            //遍历输出
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值