Java数组排序和二维数组

数组排序

数组排序指的是让一堆杂乱无章的数据,按从小到大排列,或者按从大到小排列,让其有规律。这个过程就是数组排序。排序的算法很多,例如:冒泡排序,选择排序,快速排序,归并排序,插入排序等等。咱们讲一下冒泡排序和选择排序。

冒泡排序

冒泡排序:海底的气泡由于水压的作用,越深的地方气泡就越小,气泡在上浮的过程中,由于水压的减小,气泡会越来越大,到达海面的时候,气泡会最大。基于这个启发,数学家们发明了冒泡排序。

冒泡排序的思想:以从小到大排序为例。依次比较相邻的2个数据,如果前面的数据大于后面的数据,二者交换位置,一趟下来之后,最大的数据就跑到了末尾,这个数据在下一趟不再参与比较。第二趟仍然是依次比较相邻的2个数据,如果前面的数据大于后面的数据,二者交换位置,第二趟下来之后,第2大的数据就跑到了倒数第二位,同样这个数据不再参与下一趟的比较,以此类推,对于具有n个数的数组而言,进行n-1趟上述过程,就能让数组有序。

1. 需求:有如下一组数{67, 42, 88, 16, 25, 3},对其按从小到大的顺序排列。

2. 代码:

public static void main(String[] args) {
    //需求:有如下一组数{67, 42, 88, 16, 25, 3},对其按从小到大的顺序排列。
    //分析:
    //1.创建一个数组保存上述数据
    //2.使用冒泡法进行排序
    //原始数据  67  42  88  16  25  3------一共6个数据,共比较5趟
    //第1趟,一共比较5次
    // 第1次  42  67  88  16  25  3
    // 第2次  42  67  88  16  25  3
    // 第3次  42  67  16  88  25  3
    // 第4次  42  67  16  25  88  3
    // 第5次  42  67  16  25  3   88-----88不再参与下一轮比较。第1趟找出了最大值
    //第2趟,一共比较4次
    // 第1次  42  67  16  25  3   88
    // 第2次  42  16  67  25  3   88
    // 第3次  42  16  25  67  3   88
    // 第4次  42  16  25  3   67  88-----67和88不再参与下一轮比较,第2趟找出了第2大值。
    //第3趟,一共比较3次
    // 第1次  16  42  25  3   67  88
    // 第2次  16  25  42  3   67  88
    // 第3次  16  25  3   42  67  88-----42,67,88不再参与下一轮比较,第3趟找出了第3大值
    //第4趟,一共比较2次
    // 第1次  16  25  3   42  67  88
    // 第2次  16  3   25  42  67  88-----25,42,67,88不再参与下一轮比较,第4趟找出了第4大值
    //第5趟,一共比较1次
    // 第1次  3   16  25  42  67  88-----全部数据有序。

    int[] array = {67, 42, 88, 16, 25, 3};
    for (int i = 0; i < array.length - 1; i++) {
        for (int j = 0; j < array.length - 1 - i; j++) {
            if (array[j] > array[j + 1]) {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }

    for (int i = 0; i < array.length; i++) {
        System.out.print(array[i] + " ");
    }
    System.out.println();
}

冒泡排序的格式也很固定:

for(int i = 0; i < 数组名.length - 1; i++){

        for(int j = 0; j < 数组名.length - 1 - i; j++){

                if(数组名[j] > 数组名[j+1]){

                        数据类型 temp = 数组名[j];

                        数组名[j] = 数组名[j+1];

                        数组名[j+1] = temp;

                }

        }

}

选择排序

选择排序思想:以从小到大排序为例。第一趟,从数组中找出最小值,并记录最小值的下标,让最小值与数组下标为0的元素交换位置。第二趟,刨除数组下标为0的元素,在剩下的元素中找出最小值,并记录最小值的下标,与数组下标为1的元素交换位置。第三趟,刨除数组下标为0和1的元素,在剩下的元素中找出最小值,并记录最小值的下标,与数组下标为2的元素交换位置,以此类推,如果要对n个数排序,n-1趟即可让数组有序。

1. 需求:有如下一组数{67, 42, 88, 16, 25, 3},对其按从小到大的顺序排列。

2. 代码:

public static void main(String[] args) {
    //需求:有如下一组数{67, 42, 88, 16, 25, 3},对其按从小到大的顺序排列。
    //分析:
    //1.创建一个数组保存上述数据
    //2.定义变量index保存最小值的下标。
    //3.使用选择排序法进行排序
    //原始数据  67  42  88  16  25  3------一共6个数据,共比较5趟
    //第1趟,一共比较5次  假定下标为0的元素是最小值。即index初始值是0
    // 第1次  67  42  88  16  25  3   下标为1的和下标为index的比较,下标为1的更小,将index更新为1
    // 第2次  67  42  88  16  25  3   下标为2的和下标为index的比较,下标为index比较小,不更新index
    // 第3次  67  42  88  16  25  3   下标为3的和下标为index的比较,下标为3的更小,将index更新为3
    // 第4次  67  42  88  16  25  3   下标为4的和下标为index的比较,下标为index比较小,不更新index
    // 第5次  67  42  88  16  25  3   下标为5的和下标为index的比较,下标为5的更小,将index更新为5
    //  第1趟结束后,最小的元素已经找到,即下标为5的元素,让下标为5的元素和下标为0的元素交换位置。
    //      3   42  88  16  25  67---最小值就找出来了。最小值不再参与下一趟比较。
    //第2趟,一共比较4次     假定下标为1的元素是最小值。即index初始值是1
    // 第1次  3   42  88  16  25  67  下标为2的和下标为index的比较,下标为index比较小,不更新index
    // 第2次  3   42  88  16  25  67  下标为3的和下标为index的比较,下标为3的更小,将index更新为3
    // 第3次  3   42  88  16  25  67  下标为4的和下标为index的比较,下标为index比较小,不更新index
    // 第4次  3   42  88  16  25  67  下标为5的和下标为index的比较,下标为index比较小,不更新index
    //  第2趟结束后,第二小的元素已经找到,即下标为3的元素,让下标为3的元素和下标为1的元素交换位置。
    //      3   16  88  42  25  67---最小值和次小值就找出来了。二者不再参与下一趟比较。
    //第3趟,一共比较3次     假定下标为2的元素是最小值。即index初始值是2
    // 第1次  3   16  88  42  25  67  下标为3的和下标为index的比较,下标为3的更小,将index更新为3
    // 第2次  3   16  88  42  25  67  下标为4的和下标为index的比较,下标为4的更小,将index更新为4
    // 第3次  3   16  88  42  25  67  下标为5的和下标为index的比较,下标为index比较小,不更新index
    //  第3趟结束后,第三小的元素已经找到,即下标为4的元素,让下标为4的元素和下标为2的元素交换位置。
    //      3   16  25  42  88  67---最小的3个数就找出来了。三者不再参与下一趟比较。
    //第4趟,一共比较2次     假定下标为3的元素是最小值。即index初始值是3
    // 第1次  3   16  25  42  88  67  下标为4的和下标为index的比较,下标为index比较小,不更新index
    // 第2次  3   16  25  42  88  67  下标为5的和下标为index的比较,下标为index比较小,不更新index
    //  第4趟结束后,第四小的元素已经找到,即下标为3的元素,让下标为3的元素和下标为3的元素交换位置。
    //      3   16  25  42  88  67---最小的4个数就找出来了。四者不再参与下一趟比较。
    //第5趟,一共比较1次     假定下标为4的元素是最小值。即index初始值是4
    // 第1次  3   16  25  42  88  67  下标为5的和下标为index的比较,下标为5的更小,将index更新为5
    //  第5趟结束后,第五小的元素已经找到,即下标为5的元素,让下标为5的元素和下标为4的元素交换位置。
    //      3   16  25  42  67  88---至此,数据全部有序。     

    int[] array = {67, 42, 88, 16, 25, 3};
    for (int i = 0; i < array.length - 1; i++) {
        int index = i;
        for (int j = i + 1; j < array.length; j++) {
            if (array[j] < array[index]) {
                index = j;
            }
        }
        if (index != i) {
            int temp = array[index];
            array[index] = array[i];
            array[i] = temp;
        }
    }

    for (int i = 0; i < array.length; i++) {
        System.out.print(array[i] + " ");
    }
    System.out.println();
}

选择排序的写法很固定:

for(int i = 0; i < 数组名.length - 1; i++){

        int index = i;

        for(int j = i + 1; j < 数组名.length; j++){

                if(数组名[j] < 数组名[index]){

                        index = j;

        }

}

if(index != i){

        数据类型 temp = 数组名[i];

        数组名[i] = 数组名[index];

        数组名[index] = temp;

        }

}

二维数组

数组是一个容器,可以存放数据。不仅可以存放基本数据类型,还可以存放引用类型,即数组的元素可以是数组。如果一个数组的元素是数组,这样就构成了一个二维数组。

数组存放普通数据:

数组存放数组:

二维数组的定义

二维数组的定义格式和一维数组的定义类似,分为2种:推荐使用格式一

格式一:数据类型 [] [] 数组名

示例:int [] [] arr

含义:定义了一个整型的二维数组,数组名是arr。

格式二:数据类型 数组名[] []

含义:定义了一个整型的二维数组,数组名是arr。

二维数组的初始化

二维数组的初始化也分为:动态初始化 静态初始化

动态初始化

动态初始化格式:

数据类型[] [] 数组名 = new 数据类型[第一维元素个数] [第二维元素个数];

示例:int[] [] arr = new int[4] [3];

含义:定义了一个4行3列的二维数组,数组中每个元素的初始值是0。

静态初始化

静态初始化格式:

数据类型[] [] 数组名 = new 数据类型[] []{ {值1,值2,值3..} ,{值1,值2,值3..} ,..};

示例:int[] [] arr = new int[] [] {{8, 22, 35, 17},{13, 9, 26, 21}};

含义:定义了一个2行4列的二维数组,数组的初始值是:8, 22, 35, 17, 13, 9, 26, 21

静态初始化的简化格式:

数据类型[] [] 数组名 = { {值1,值2,值3..} ,{值1,值2,值3..} ,..};

示例:int[] [] arr = {{8, 22, 35, 17},{13, 9, 26, 21}};

含义:定义了一个2行4列的二维数组,数组的初始值是:8, 22, 35, 17, 13, 9, 26, 21

二维数组的使用场景

1. 游戏的地图

2. 游戏里的背包、储物柜

3. 彩票购买软件里,多注彩票的存储

4. 修图软件里图片的像素

...

二维数组的访问

访问二维数组

数组名代表整个二维数组。数组名存储的是整个二维数组的起始地址。

如果打印数组名,将会显示一个地址值。

给数组名赋值,将改变二维数组的指向。

public static void main(String[] args) {
    int[][] arr = {{8, 22, 35, 17},{13, 9, 26, 21}};
    System.out.println(arr);//二维数组在堆区的起始地址
}

访问第一维(行)

语法格式:数组名[第一维的下标]

由于二维数组可以看成1个元素是数组的一维数组。因此 数组名[第一维的下标] 获取的是内层数组的地址

如果打印 数组名[第一维的下标] 得到的是一个地址值。

public static void main(String[] args) {
    int[][] arr = {{8, 22, 35, 17},{13, 9, 26, 21}};
    System.out.println(arr);//二维数组在堆区的起始地址
    System.out.println(arr[0]);//二维数组第1行元素在堆区的起始地址
    System.out.println(arr[1]);//二维数组第2行元素在堆区的起始地址
}

二维数组元素的访问

语法格式: 数组名[第一维的下标] [第二维的下标]

示例: arr[1] [2]

含义:访问的是二维数组第2行第3列的元素。

数组名[第一维的下标] [第二维的下标] 可以看成是一个特殊的变量,因此可以对其进行赋值和取值。

public static void main(String[] args) {
    int[][] arr = {{8, 22, 35, 17},
            {13, 9, 26, 21}};
    int num = arr[0][1];//将第一行第二列元素22赋值给num
    System.out.println(num);
    arr[1][1] = 100;//把100赋值给第二行第二列的元素。
    System.out.println(arr[1][1]);
}

二维数组的内存分配

在Java中二维数组本身有一个堆区空间,内部每一个一维数组也有自己独立的堆区空间。二维数组中存储的是每一个一维数组的起始地址。

在C语言中,二维数组所有元素的内存是连续的。

二维数组注意事项

数组下标越界

每一维的下标都不能越界。

空指针异常

二维数组的数组名赋值为null的时候,不能再操作数据。

二维数组内的每个一维数组赋值为null的时候,不能再操作数据。

二维数组的遍历

二维数组的遍历指的是找到数组中每个元素。通常使用循环嵌套来遍历数组元素。

遍历二维数组的通用格式

数据类型[][]  数组名 = new 数据类型[第一维元素个数][第二维元素个数];
for(int i = 0; i < 数组名.length; i++){
        for(int j = 0; j < 数组名[i].length; j++){
数组名[i][j] // 数组名[i][j]就是具体的元素。
        }
}

二维数组遍历示例

1. 需求:定义一个二维数组{{8, 22, 35, 17}, {13, 9, 26, 21}},遍历数组中的元素。

2. 代码:

public static void main(String[] args) {
    int[][] arr = {{8, 22, 35, 17},
            {13, 9, 26, 21}};
    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();
    }
}

二维数组案例

1. 需求:创建一个3行5列的二维数组,每个元素的取值范围是[30, 70]。

2. 代码:

public static void main(String[] args) {
    //需求:创建一个3行5列的二维数组,每个元素的取值范围是[30, 70]。
    //分析:
    //1.创建一个3行5列的二维数组
    //2.创建Random对象
    //3.通过循环为二维数组赋值。
    int[][] arr =  new int[3][5];
    Random random = new Random();
    for(int i = 0; i < arr.length; i++) {
        for(int j = 0; j < arr[i].length; j++) {
            arr[i][j] = random.nextInt(70 - 30 + 1) + 30;
            System.out.print(arr[i][j] + " ");
        }
        System.out.println();
    }
}

3. 需求:创建一个3行5列的二维数组,每个元素的取值范围是[30, 70],求数组中的最大值。

4. 代码:

public static void main(String[] args) {
    //需求:创建一个3行5列的二维数组,每个元素的取值范围是[30, 70],求数组中的最大值。
    //分析:
    //1.创建一个3行5列的二维数组
    //2.定义一个变量max保存最大值
    //3.创建Random对象
    //4.通过循环为二维数组赋值。在赋值的过程中,判断元素和max谁大,如果元素大,把元素赋值给max
    int[][] arr = new int[3][5];
    int max = 0;
    Random random = new Random();
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[i].length; j++) {
            arr[i][j] = random.nextInt(70 - 30 + 1) + 30;
            System.out.print(arr[i][j] + " ");
            if (arr[i][j] > max) {
            }
            max = arr[i][j];
        }
        System.out.println();
    }
    System.out.println("max = " + max);
}

三维数组

上图就是三维数组的一个模型。一维数组是线性的,二维数组是平面,有行和列的概念,三维数组是一个立体,有长宽高的概念。

三维数组的定义

数据类型[] [] [] 数组名 = new 数据类型[第一维元素个数] [第二维元素个数] [第三维元素个数];

示例:

int[] [] [] arr = new int[3] [4] [3];

含义:定义了一个3层4行3列的数组。即一共3层,每层4行,每行3列。

三维数组元素的访问

数组名[下标1] [下标2] [下标3]

示例:

arr[0] [1] [1] = 30;//将第1层,第2行,第2列的值设置为30

int num = arr[0] [1] [1]; //将第1层,第2行,第2列的值赋值给num

三维数组的遍历

数据类型[][][] 数组名 = new 数据类型[第一维元素个数][第二维元素个数][第三维元素个数];
for(int i = 0; i < 数组名.length; i++){
    for(int j = 0; j < 数组名[i].length; j++){
        for(int k = 0; k < 数组名[i][j].length; k++){
数组名[i][j][k] //数组名[i][j][k]就是被遍历到的数组元素
        }
    }
}

三维数组示例

1. 需求:创建一个3层3行5列的三维数组,每个元素是[10, 80]之间的随机数,找出数组中的最大值,以及最大值元素的下标。

2. 代码:

public static void main(String[] args) {
    //需求:创建一个3层3行5列的三维数组,每个元素是[10, 80]之间的随机数.
    //找出数组中的最大值,以及最大值元素的下标。
    //分析:
    //1.创建一个三维数组
    //2.创建Random对象
    //3.定义一个变量max保存元素的最大值
    //4.通过循环为数组赋值,并求出最大值。
    int[][][] arr = new int[3][3][5];
    Random random = new Random();
    int max = 0;
    for(int i = 0; i < arr.length; i++) {
        for(int j = 0; j < arr[i].length; j++) {
            for(int k = 0; k < arr[i][j].length; k++) {
                arr[i][j][k] = random.nextInt(80 - 10 + 1) + 10;
                System.out.print(arr[i][j][k] + " ");
                if(arr[i][j][k] > max) {
                    max = arr[i][j][k];
                }
            }
            System.out.println();
        }
        System.out.println();
    }
    System.out.println("max = " + max);

    //找最大值的下标
    for(int i = 0; i < arr.length; i++) {
        for(int j = 0; j < arr[i].length; j++) {
            for(int k = 0; k < arr[i][j].length; k++) {
                if(arr[i][j][k] == max) {
                    System.out.println("i = " + i + ",j = " + j + ",k = " + k);
                }
            }
        }
    }
}

多维数组

多维数组的定义

数据类型 []...[] 数组名 = new 数据类型[第1维元素个数] ...[第n维元素个数];

多维数组元素的访问

数组名[下标1]..[下标n]

多维数组的遍历----n层循环

数据类型[]...[] 数组名 = new 数据类型[第一维元素个数]...[第n维元素个数];
for(int i = 0; i < 数组名.length; i++){
    for(int j = 0; j < 数组名[i].length; j++){
        ...{
                for(int k = 0; k < 数组名[i][j].length; k++){
数组名[i]...[k] //数组名[i]...[k]就是被遍历到的数组元素
                }
            }
    }
}

常用

1. 数组是一个容器,用于存储数据。数组在创建的时候要确定容量,数组内部的元素类型必须相同。

2. 数组的长度:数组名.length

3. 数组可以动态初始化,也可以静态初始化。

4. 数组的遍历,几维数组就用几层循环嵌套来遍历。

5. 数组通常和循环结合使用。

6. 数组元素的访问:数组名[下标] -----几维数组就要有几个下标。

  • 29
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值