JavaSE进阶 | 二维数组的定义和使用、查找和排序算法

这篇具有很好参考价值的文章主要介绍了JavaSE进阶 | 二维数组的定义和使用、查找和排序算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

🥅二维数组

❤️二维数组的遍历

❤️动态初始化二维数组

🥅数组知识点总结

🥅习题练习

❤️用数组模拟栈

❤️模拟酒店的订房退房功能

❤️杨辉三角

❤️把数据存入数组,保证值各不相同

❤️数组元素的赋值与数组复制

❤️数组元素的反转

❤️数组的扩容与缩容

🥅查找和排序算法

❤️直接调用封装好的工具类来排序

❤️冒泡排序算法

❤️选择排序算法

❤️二分查找

❤️Arrays工具类的使用


🥅二维数组

(1)二维数组其实是一个特殊的一维数组,特殊在这个一维数组当中的每一个元素是一个一维数组。
(2)三维数组是什么?
        三维数组是一个特殊的二维数组,特殊在这个二维数组中每一个元素是一个一维数组。
        实际的开发中使用最多的就是一维数组。二维数组也很少使用。三维数组几乎不用。
(3)二维数组静态初始化
        int[][] array = {{1,1,1},{2,3,4,5},{2,3,4,5}};

package com.bjpowernode.javase.array;

public class ArrayTest1 {
    public static void main(String[] args) {
        //对于一维数组
        int[] array = {100,200,300};
        System.out.println(array.length); //3
        //二维数组初始化
        int[][] arr = {{1,2,3},{4,5,6},{6,7},{0}};
        System.out.println(arr.length); //4,看里面有几个一维数组
        System.out.println(arr[0].length);// 3,第一个一维数组元素的个数
        //取出二维数组的第一个一维数组,所以用一个一维数组进行接收
        int[] a0 = arr[0];
        //遍历这个一维数组
        for (int i = 0; i < a0.length; i++) {
            //System.out.println(a0[i]);
            System.out.println(arr[0][i]); //与上面是等价的
        }

    }
}

❤️二维数组的遍历

package com.bjpowernode.javase.array;

public class ArrayTest2 {
    public static void main(String[] args) {
        String[][] array = {
                {"java", "oracle", "c++", "python", "c#"},
                {"张三", "李四", "王五"},
                {"lucy", "jack", "rose"}
        };
        //二维数组的遍历
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]+" ");
            }
            System.out.println();
        }
    }
}

❤️动态初始化二维数组

package com.bjpowernode.javase.array;

public class ArrayTest3 {
    public static void main(String[] args) {
        // 1.动态初始化
        int[][] arr = new int[3][4];
        // 2.遍历
        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();
        }

        // 3.利用printArray方法遍历整个二维数组
        int[][] a = {{1,2,3,44},{23,45,8},{55,99}}; //静态初始化
        printArray(a); //第一种传参方法
        printArray(new int[][]{{1,2,3,44},{23,45,8},{55,99}});//第二种传参方法

    }
    //静态方法
    public static void printArray(int[][] 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();
        }

    }
}

🥅数组知识点总结

数组的优点和缺点,并且要理解为什么。
第一:空间存储上,内存地址是连续的。
第二:每个元素占用的空间大小相同。
第三:知道首元素的内存地址;通过下标可以计算出偏移量。

通过一个数学表达式,就可以快速计算出某个下标位置上元素的内存地址,直接通过内存地址定位,效率非常高。

优点:检索效率高。
缺点:随机增删效率较低,数组无法存储大数据量;
数组最后一个元素的增删效率不受影响

一维数组的静态初始化和动态初始化

静态初始化:       

  int[] arr = {1,2,3,4};
  Object[] objs = {new Object(), new Object(), new Object()};

动态初始化:    

    int[] arr = new int[4]; // 4个长度,每个元素默认值0
    Object[] objs = new Object[4]; // 4个长度,每个元素默认值null

一维数组的遍历

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

二维数组的静态初始化和动态初始化

 静态初始化:

    int[][] arr = {
                       {1,2,34},
                       {54,4,34,3},
                       {2,34,4,5}
                   };

     Object[][] arr = {
                          {new Object(),new Object()},
                          {new Object(),new Object()},
                          {new Object(),new Object(),new Object()}
                       };

动态初始化:   

int[][] arr = new int[3][4];
Object[][] arr = new Object[4][4];
Animal[][] arr = new Animal[3][4];
//Person类型数组,里面可以存储Person类型对象,以及Person类型的子类型都可以
Person[][] arr = new Person[2][2];
....

二维数组的遍历   

 for(int i = 0; i < arr.length; i++){ // 外层for循环负责遍历外面的一维数组。
            // 里面这个for循环负责遍历二维数组里面的一维数组。
            for(int j = 0; j < arr[i].length; j++){
                System.out.print(arr[i][j]);
            }
            System.out.println();
        }

数组的拷贝:System.arraycopy()方法的使用
数组有一个特点:长度一旦确定,不可变
所以数组长度不够的时候,需要扩容,扩容的机制是:新建一个大数组,将小数组中的数据拷贝到大数组,然后小数组对象被垃圾回收。

🥅习题练习

❤️用数组模拟栈

编写程序,使用一维数组,模拟栈数据结构。要求:
(1)这个栈可以存储java中的任何引用类型的数据。
(2)在栈中提供push方法模拟压栈。(栈满了,要有提示信息)
(3)在栈中提供pop方法模拟弹栈。(栈空了,也有有提示信息)
(4)编写测试程序,new栈对象,调用push pop方法来模拟压栈弹栈的动作。
(5)假设栈的默认初始化容量是10.(再无参数构造方法中初始化)

栈可以存储java中的任何引用类型的数据该怎样定义?我们来通过下面这个简单例题来了解一下!

//一个栈可以存储java中的任何引用类型的数据=====>这个数组类型是Object

// Object[] 这是一个万能的口袋,这个口袋中可以装任何引用数据类型的数据。
public class HomeworkStack {
    public static void main(String[] args) {
          
        // 注意:"abc" 这是一个字符串对象,字符串在java中有优待,不需要new也是一个对象。
        // "abc" 字符串也是java对象,属于String类型。也可以new出来,例如:
        //String s = new String("abc");
        String s = "abc"; //与上面是等价的
        
        //--------定义为一个Object类型的数组进行数据存储
        Object[] obj = {new Husband(),new Wife(),"abc"};
        for (int i = 0; i < obj.length; i++) {
            System.out.println(obj[i]);
        }
    }

}

class Husband{

}

class Wife{

}

具体代码实现:

对于记录元素个数的sz,初始化为0或-1都是可以的:

①sz = 0,先放数据,再sz++。

②sz = -1,先sz++,再放数据。

//--------模拟栈的实现,具体代码
package com.bjpowernode.javase.array.homework;

public class MyStack {
    // 为什么选择Object类型数组?因为这个栈可以存储java中的任何引用类型的数据
    // new Animal()对象可以放进去,new Person()对象也可以放进去。因为Animal和Person的超级父类就是Object。
    // 包括String也可以存储进去。因为String父类也是Object。
    private Object[] object;
    // 栈帧,永远指向栈顶部元素
    // 那么这个默认初始值应该是多少。注意:最初的栈是空的,一个元素都没有。
    //private int sz = 0; // 如果index采用0,表示栈帧指向了顶部元素的上方。
    //private int sz = -1; // 如果index采用-1,表示栈帧指向了顶部元素。
    private int sz;

    //无参构造方法
    public MyStack() {
        this.object = new Object[10];
        this.sz= -1;
    }

    //push方法模拟压栈。(栈满了,要有提示信息。)
    public void push(Object obj){ //传过来是一个对象的地址
        if(sz >= object.length-1){
            System.out.println("栈已满,压栈失败");
            return;
        }
        //因为是从-1开始,要先sz++在压栈
        sz++;
        object[sz] = obj; //也可以合并object[++sz] = obj
        System.out.println("压栈"+obj+"元素成功,栈帧指向"+sz);
    }

    //pop方法模拟弹栈。(栈空了,也有有提示信息。)
    public void pop(){
        if(sz < 0){
            System.out.println("栈已空,弹栈失败");
            return;
        }
        System.out.println("弹栈"+object[sz]+"元素成功");
        sz--;
        System.out.println("栈帧指向"+sz);
    }

    //set和get方法----这里实际上没有什么用处,也要写
    public Object[] getObject() {
        return object;
    }
    public void setObject(Object[] object) {
        this.object = object;
    }
    public int getIndex() {
        return sz;
    }
    public void setIndex(int index) {
        this.sz = index;
    }

}

测试程序:

//测试程序
package com.bjpowernode.javase.array.homework;

public class MyStackTest {
    public static void main(String[] args) {
        MyStack m = new MyStack();
        //压栈
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());

        //结束
        m.push(new Object());
        //弹栈
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        //结束
        m.pop();

    }
}

❤️模拟酒店的订房退房功能

为某个酒店编写程序:酒店管理系统,模拟订房、退房、打印所有房间状态等功能。
(1)该系统的用户是:酒店前台。
(2)酒店使用一个二维数组来模拟。“Room[][] rooms;”
(3)酒店中的每一个房间应该是一个java对象:Room
(4)每一个房间Room应该有:房间编号、房间类型、房间是否空闲.
(5)系统应该对外提供的功能:
       可以预定房间:用户输入房间编号,订房。
       可以退房:用户输入房间编号,退房。
       可以查看所有房间的状态:用户输入某个指令应该可以查看所有房间状态。

⭐第一步:先抽出Room类

package com.bjpowernode.javase.array.homework.hotle;
//酒店的房间

public class Room {
    private int id; // 房间号
    private String type; // 房间的类型
    private boolean status; // 房间的状态

    //构造方法
    public Room() {
    }
    public Room(int id, String type, boolean status) {
        this.id = id;
        this.type = type;
        this.status = status;
    }
    //setter and getter
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }

    public boolean isStatus() {
        return status;
    }
    public void setStatus(boolean status) {
        this.status = status;
    }

    //重写toString方法
    public String toString() {
        return "["+id+","+type+","+(status?"空闲":"占用")+"]";
    }

    //重写equals方法
    public boolean equals(Object obj) {
        if(obj == null || !(obj instanceof Room)){
            return false;
        }
        if(this == obj){
            return true;
        }
        Room room = (Room)obj;
        return this.getId() == room.getId();
    }
}

⭐第二步:基于房间类写出酒店类

package com.bjpowernode.javase.array.homework.hotle;
//酒店对象,酒店中有二维数组,二维数组模拟大厦
//假设一共有三层,一层单人间、二层标准间、三层总统套房,每层10个房间
public class Hotel {
    //酒店的房间是以二维数组的形式展现的
    private Room[][] rooms;

    //构造方法
    public Hotel() {
        //利用无参构造方法进行初始化
        rooms = new Room[3][10]; //进行盖楼

        //进行创建房间
        for (int i = 0; i < rooms.length; i++) {
            for (int j = 0; j < rooms[i].length; j++) {
                if (i == 0) {
                    rooms[i][j] = new Room((i + 1) * 100 + (j + 1), "单人间", true);
                } else if (i == 1) {
                    rooms[i][j] = new Room((i + 1) * 100 + (j + 1), "标准间", true);
                } else if (i == 2) {
                    rooms[i][j] = new Room((i + 1) * 100 + (j + 1), "豪华间", true);
                }
            }
        }

    }

    //打印房间状态
    public void print(){
        for (int i = 0; i < rooms.length; i++) {
            for (int j = 0; j < rooms[i].length; j++) {
                System.out.print(rooms[i][j]); //默认调用toString()方法
            }
            System.out.println();
        }
    }

    //订房
    public void order(int roomId){
        //通过房间号,转换成对应的二维数组
        //rooms[roomId/10+1][roomId%10+1].setStatus(false);
        Room room = rooms[roomId/100-1][roomId%100-1];
        if(room.isStatus()){
            room.setStatus(false);
            System.out.println("已成功订房");
        }else{
            System.out.println("房间已被占用,订房失败");
        }
    }
    //退房
    public void exit(int roomId){
        Room room = rooms[roomId/100-1][roomId%100-1];
        room.setStatus(true);
        System.out.println("已成功退房");
    }
}


⭐第三步:测试程序

package com.bjpowernode.javase.array.homework.hotle;
//----学会进行拆分:从一个单房间---》到整个酒店---》测试程序
import java.util.Scanner;
public class SystemHotels {
    public static void main(String[] args) {
        /*Room room = new Room(101,"单人间",true);
        Room room1 = new Room(102,"单人间",true);
        System.out.println(room.equals(room1));
        System.out.println(room);*/

        //创建酒店对象
        Hotel hotel = new Hotel();

        //界面处理
        System.out.println("欢迎使用酒店管理系统,请认真阅读使用说明");
        System.out.println("请输入对应的功能标号:[1]看到房间状态,[2]订房,[3]退房,[0]退出系统");
        Scanner s = new Scanner(System.in);

        while(true){
            System.out.print("请输入功能编号:");
            int i = s.nextInt();

            if(i == 1){
                //查看房间状态
                hotel.print();
            }else if(i == 2){
                //订房
                System.out.print("请输入住房房间编号:");
                int roomId = s.nextInt();
                hotel.order(roomId);
            }else if(i == 3){
                //退房
                System.out.print("请输入退房房间编号:");
                int roomId = s.nextInt();
                hotel.exit(roomId);
            }else if(i == 0){
                //退出系统
                System.out.println("退出程序");
                break;
            }else{
                //选择错误
                System.out.println("选择错误,请重新选择");
            }
        }
    }

}

❤️杨辉三角

掌握一二维数组的定义和使用并熟练掌握排序和查找算法,第一步:JavaSE从入门到精通,java,开发语言

(1)第一行有 1 个元素, 第 n 行有 n 个元素; 

(2)每一行的第一个元素和最后一个元素都是 1; 

(3)从第三行开始, 对于非第一个元素和最后一个元素的元素,满足以下代码;即:arr[i][j] = arr[i-1][j-1] + arr[i-1][j];

package com.zl.test;

public class ArrayTest {
    public static void main(String[] args) {
        // 动态创建一个二维数组
        int[][] arr = new int[10][];
        for (int i = 0; i < arr.length; i++) {
            // 初始化列的大小
            arr[i] = new int[i+1]; // 例如:每个下标n(下标从0开始),存储n+1个数据
            for (int j = 0; j <= i; j++) {
                if(j == 0 || i == j){
                    arr[i][j] = 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++) {
                System.out.printf(arr[i][j]+"\t");
            }
            System.out.println();
        }
    }
}

 

❤️把数据存入数组,保证值各不相同

创建一个长度为 10 的 int 型数组,要求数组元素的值都在 1-20 之间, 且是随机赋值;同时,要求元素的值各不相同。

package com.zl.test;

public class ArrayTest2 {
    public static void main(String[] args) {
        // 初始化数组
        int[] arr = new int[10];
        // 获取随机数
        int count = 0;
        while (count < arr.length) {
            int num = (int) (Math.random() * (20 - 1) + 1) + 1;
            // 判断当前数据是否在数组当中
            boolean b = isContain(arr, num);
            if (!b) { // 不存在就放入数组当中
                arr[count] = num;
                count++;
            }
        }
        // 打印
        print(arr);
    }
    // 封装的这个方法用来判断生成的数据是否在当前数组里
    private static boolean isContain(int[] arr, int num) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == num) {
                return true;
            }
        }
        return false;
    }

    // 封装打印的方法
    private static void print(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i]+"\t");
        }
    }
}

❤️数组元素的赋值与数组复制

(1)数组元素的赋值,是把整个数组(数组首元素的地址)赋值给另一个数组,实际上两个数组指向同一组数组元素,只要其中一个修改,另一个就会被修改。

(2)数组元素的复制,此时就需要new一个与第一个数组相同大小的数组,然后进行遍历赋值,此时就相当于复制,进行更改不会影响原先数组的内容。

赋值

package com.zl.test;

public class ArrayTest03 {
    public static void main(String[] args) {
        // 准备一个数组
        int[] arr = new int[]{2,3,4,7,8,9,11,12};
        print(arr); // 更改arr2前进行打印
        // 数组的赋值
        int[] arr2 = arr;
        for (int i = 0; i < arr2.length; i++) {
            // 此时数值arr2进行更改会影响到arr
            if (i % 2 == 0){
                arr2[i] = i;
            }
        }
        System.out.println();
        print(arr); // 更改arr2之后打印
    }

    public static void print(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i]+"\t");
        }
    }
}

执行结果:更改arr2数组的值会影响arr数组的值,指向的是同一个数组

掌握一二维数组的定义和使用并熟练掌握排序和查找算法,第一步:JavaSE从入门到精通,java,开发语言

 

复制

package com.zl.test;

public class ArrayTest04 {
    public static void main(String[] args) {
        // 准备一个数组
        int[] arr = new int[]{2,3,4,7,8,9,11,12};
        print(arr); // 更改arr2前进行打印
        // 数组的复制
        // 先创建一个相同大小的数组
        int[] arr3 = new int[arr.length];
        // 遍历这个数组,把arr中的值赋值给arr3
        for (int i = 0; i < arr3.length; i++) {
            arr3[i] = arr[i];
        }
        // 此时数值arr3进行更改不会影响到arr
        for (int i = 0; i < arr3.length; i++) {

            if (i % 2 == 0){
                arr3[i] = i;
            }
        }
        
        System.out.println();
        print(arr); // 更改arr2之后打印
    }

    public static void print(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i]+"\t");
        }
    }
}

执行结果:此时修改arr3的值就不会影响到arr,因为是新new的

掌握一二维数组的定义和使用并熟练掌握排序和查找算法,第一步:JavaSE从入门到精通,java,开发语言

 

❤️数组元素的反转

核心思想:

掌握一二维数组的定义和使用并熟练掌握排序和查找算法,第一步:JavaSE从入门到精通,java,开发语言

方法一:定义一个变量控制

package com.zl.test;

public class ArrayTest05 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9};
        for (int i = 0; i < arr.length / 2; i++) {
            int tmp = arr[i];
            arr[i] = arr[arr.length-1-i];
            arr[arr.length-1-i] = tmp;
        }
        // 打印
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i]+"\t");
        }
    }
}

方法二:定义两个变量控制

package com.zl.test;

public class ArrayTest05 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9};
        // 旋转数组
        // i从最左边开始,j从最右边开始
        for (int i = 0,j=arr.length-1; i < j; i++,j--) {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }

        // 打印
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i]+"\t");
        }
    }
}

方法三:创建一个新的临时数组,进行反向赋值(不推荐)

package com.zl.test;

public class ArrayTest05 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9};
     
        // 创建一个相同大小的数组
        int[] newArr = new int[arr.length];
        // 进行遍历赋值
        for (int i = newArr.length-1; i >= 0; i--) {
            newArr[newArr.length-1-i] = arr[i]; // newArr的第一个赋值为arr最后一个
        }

        arr = newArr; // 最后在赋值给arr,此时newArr就相当于一个临时数组
        // 打印a
        for (int i = 0; i < arr.length; i++) {
            System.out.printf(arr[i]+"\t");
        }
    }
}

❤️数组的扩容与缩容

数组的扩容

题目:现有数组 int[] arr = new int[]{1,2,3,4,5}; ,现将数组长度扩容 1 倍,并将 10,20,30 三个数据添加到 arr 数组中,如何操作?

package com.zl.test;

public class ArrayTest06 {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5};
        // 创建一个新数组
        int[] newArr = new int[arr.length << 1]; // 左移一位变大2倍
        // 进行赋值
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = arr[i];
        }
        newArr[arr.length] = 10;
        newArr[arr.length+1] = 20;
        newArr[arr.length+2] = 30;
        // 重新赋值给原来的数组
        arr = newArr;
        // 进行打印
        for (int i = 0; i < newArr.length; i++) {
            System.out.print(newArr[i]+"\t");
        }
    }
}

数组的缩容

题目:现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为 4 的元素。

package com.zl.test;

public class ArrayTest07 {
    public static void main(String[] args) {
        int[] arr={1,2,3,4,5,6,7};
        int index = 4;
        // 删除下标为4的元素,就把4之后的数据都往前移一位
        for (int i = index; i < arr.length-1; i++) { // 注意这里i的范围是【index-arr.length-2】
            arr[i] = arr[i+1];
        }
        arr[arr.length-1] = 0;
        // 循环打印
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+"\t");
        }
    }
}

 

🥅查找和排序算法

(1)常见的算法:

排序算法:冒泡排序算法、选择排序算法

查找算法:二分法查找
以上算法在以后的java实际开发中我们不需要使用的,因为java已经封装好了,直接调用就行。但面试可能会考!
(2)算法实际上在java中不需要精通,因为java中已经封装好了,
要排序就调用方法就行,例如:java中提供了一个数组工具类:Arrays(java.util);Arrays是一个工具类。其中有一个sort()方法,可以排序,例如:Arrays.sort(arr);。静态方法,直接使用类名调用就行!

2.3、怎么查找Arrays工具类?

      双击shift---》输入Arrays--->选择Classes---》找到Arrays(java.util)

掌握一二维数组的定义和使用并熟练掌握排序和查找算法,第一步:JavaSE从入门到精通,java,开发语言

❤️直接调用封装好的工具类来排序

package com.bjpowernode.javase.array;

import java.util.Arrays;

//使用Sun公司提供的数组工具类:java.util.Arrays;
public class ArraysSort01 {
    public static void main(String[] args) {
        //数组
        int[] arr = {11,5,7,3,9,2};
        //排序;工具当中的方法大部分都是静态的,直接调用
        Arrays.sort(arr);
        //打印输出
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" "); //2 3 5 7 9 11
        }
    }
}

❤️冒泡排序算法

(1)冒泡排序对于n个数据总共要循环n-1次,每次循环需要比较n-1-i个数据!

(2)可以定义flag变量,作为一个标记,一次循环下来没有发生交换,flag的值也就没有变,说明后面都是有序;所以就可以跳出循环,不需要再进行比较,大大提高效率。

package com.bjpowernode.javase.array;
//冒泡排序算法
public class BubbleSort {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        //冒泡排序
        int count = 0;// 用来统计比较次数
        int sum = 0; //用来统计交换次数
        //-----------第一种写法
       for (int i = 0; i < arr.length-1; i++) {
           int flag = 1; //如果第二次循环flag还是1说明后面已经有序了
            for (int j = 0; j < arr.length-i-1; j++) {
                count++; //统计比较次数
                if(arr[j]>arr[j+1]){
                    int tmp = arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=tmp;
                    sum++; // 统计交换次数
                    flag = 0;
                }
            }
            if(flag == 1){
                //说明后面就是有序的,就不用在交换了
                break;
            }
        }
        System.out.println("比较次数是:"+count);
        System.out.println("交换次数是:"+sum);
        //-----------第二种写法
       /* for (int i = arr.length-1; i >0; i--) {
            for (int j = 0; j < i; j++) {
                if(arr[j]>arr[j+1]){
                    int tmp = arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=tmp;
                }
            }
        }*/
        //打印
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

}

❤️选择排序算法

(1) 每一次从这堆“参与比较的数据当中”找出最小值,拿着这个最小值和“参与比较的这堆最前面的元素”交换位置。

(2)选择排序比冒泡排序好在:每一次的交换位置都是有意义的。

        关键点:选择排序中的关键在于,你怎么找出一堆数据中最小的。
(3)选择排序每次循环结束后都能确定一个元素的位置   

(4)选择排序比冒泡排序的效率高;高在交换位置的次数上;选择排序的交换位置是有意义的;循环一次,然后找出参加比较的这堆数据中最小的,拿着这个最小的值和最前面的数据“交换位置”。

例如:参与比较的数据:3 1 6 2 5 (这一堆参加比较的数据中最左边的元素下标是0)
(1)第1次循环之后的结果是:1 3 6 2 5 

    参与比较的数据:3 6 2 5 (这一堆参加比较的数据中最左边的元素下标是1)

(2)第2次循环之后的结果是:2 6 3 5 

    参与比较的数据:6 3 5 (这一堆参加比较的数据中最左边的元素下标是2)
(3)第3次循环之后的结果是:3 6 5 

    参与比较的数据:6 5 (这一堆参加比较的数据中最左边的元素下标是3)

(4)第4次循环之后的结果是:5 6

注意:5条数据,循环4次。

(5)重要结论:冒泡排序和选择排序最本质的区别是,比较次数没变,交换次数后者更小

package com.bjpowernode.javase.array;
//选择排序
public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {9, 8, 10, 7, 6, 0, 11};
        int count = 0; // 比较次数
        int sum = 0; // 交换次数

        //n个数据需要循环n-1次
        for (int i = 0; i < arr.length-1; i++) {
            //每次循环,都能确定一个数据的位置,所以要比较的数据都少1个
            //假设每次比较起点i下标位置上的元素是最小的。
            int min = i;
            for (int j = i+1; j < arr.length; j++) {
                count++;
                if(arr[j]<arr[min]){ // 目的是找到最小值
                    min = j;
                }
            }

            // 当i和min相等时,表示最初猜测是对的。
            // 当i和min不相等时,表示最初猜测是错的,有比这个元素更小的元素,
            // 需要拿着这个更小的元素和最左边的元素交换位置。
            if(min != i){
                int tmp = arr[min];
                arr[min] = arr[i];
                arr[i] = tmp;
                sum++;
            }
        }
        System.out.println("比较次数:"+count); //21
        System.out.println("交换次数:"+sum); //5
        //遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }

    }
}

❤️二分查找

1、遍历查找,一个一个找

package com.bjpowernode.javase.array;

public class ArraySearch {
    public static void main(String[] args) {
        int[] arr = {9,4,6,3,2,1};
        //封装成函数
        int index = arraySearch(arr,1);
        System.out.println(index == -1?"该元素不存在":"该元素下标是:"+index);
    }

    public static int arraySearch(int[] arr, int i) {
        for (int j = 0; j < arr.length; j++) {
            if(arr[j] == i){
                return j;
            }
        }
        return -1;
    }


}

2、利用二分查找

第一:二分法查找一定是建立在有序的基础之上!
第二:二分法查找效率要高于“一个挨着一个”的这种查找方式。
第三:二分法查找原理?

例如: 10(0下标) 23 56 89 100 111 222 235 500 600(下标9) arr数组    
(1)目标:找出222的下标
            (0 + 9) / 2 --> 4(中间元素的下标)
           arr[4]这个元素就是中间元素:arr[4]是 100;100 < 222
           说明被查找的元素在100的右边;那么此时开始最左边的下标变成:4 + 1

(2)   (5 + 9) / 2 --> 7(中间元素的下标):arr[7] 对应的是:235;235>222
            说明被查找的元素在235的左边;开始最右边下标进行了转变:7-1
(3)   (5+6) / 2 --> 5;arr[5] --> 111 ;111<222
              说明被查找的元素在111的右边;那么此时开始最左边的下标变成:5 + 1
 (4)    (6+6) / 2 --> 6
            arr[6]是222,正好和222相等,此时找到了。

package com.bjpowernode.javase.array;
//二分查找
public class BinarySearch {
    public static void main(String[] args) {
        int[] arr = {13,15,17,23,25,27,28,55};
        int index = binarySearch1(arr,27);
        System.out.println(index==-1?"没找到":"找到了,下标是"+index);
    }

    public static int binarySearch1(int[] arr, int i) {
        int left = 0;
        int right = arr.length-1;
        while(left <=right ){
            int mid = (left+right)/2;
            if(arr[mid]>i){
                //说明在mid的左边,right = mid-1
                right = mid-1;
            }else if(arr[mid]<i){
                //说明在mid的右边,left = mid+1
                left = mid+1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}

❤️Arrays工具类的使用

java.util.Arrays 类即为操作数组的工具类,包含了用来操作数组(比如排序和搜 索)的各种方法。 比如:   

(1)数组元素拼接:

①static String toString(int[] a) :字符串表示形式由数组的元素列表组成,括 在方括号("[]")中。相邻元素用字符 ", "(逗号加空格)分隔。形式为: [元素 1,元素 2,元素 3。。。] 。

②static String toString(Object[] a) :字符串表示形式由数组的元素列表组 成,括在方括号("[]")中。相邻元素用字符 ", "(逗号加空格)分隔。元素将自动调用自己从 Object 继承的 toString 方法将对象转为字符串进行拼 接,如果没有重写,则返回类型@hash 值,如果重写则按重写返回的字符 串进行拼接。 

int[] arr={1,2,3,4,5,6,7};
String s = Arrays.toString(arr);
System.out.println(s); //[1, 2, 3, 4, 5, 6, 7]

(2)数组排序:

①static void sort(int[] a) :将 a 数组按照从小到大进行排序。

②static void sort(int[] a, int fromIndex, int toIndex) :将 a 数组的[fromIndex, toIndex)部分按照升序排列 。

③static void sort(Object[] a) :根据元素的自然顺序对指定对象数组按升序进行排序。

④static void sort(T[] a, Comparator c) :根据指定比较器产生的 顺序对指定对象数组进行排序。

int[] arr={7,4,3,2,9,10};
Arrays.sort(arr);
for (int i = 0; i < arr.length; i++) {
     System.out.printf(arr[i]+"\t"); // 2	3	4	7	9	10
  }

(3)数组元素的二分查找:

static int binarySearch(int[] a, int key) 、static int binarySearch(Object[] a, Object key) :要求数组有序,在数组中查找 key 是否存在,如果存在返回 第一次找到的下标,不存在返回负数。

int[] arr={1,2,3,4,5,6,7}; // 数组要有序
int flag = Arrays.binarySearch(arr, 5);
System.out.println(flag); // 4

(4)数组的复制:

①static int[] copyOf(int[] original, int newLength) :根据 original 原数组复制 一个长度为 newLength 的新数组,并返回新数组 。

② static T[] copyOf(T[] original,int newLength):根据 original 原数组复制一 个长度为 newLength 的新数组,并返回新数组 。

③ static int[] copyOfRange(int[] original, int from, int to) :复制 original 原数 组的[from,to)构成新数组,并返回新数组。

④static T[] copyOfRange(T[] original,int from,int to):复制 original 原数组的 [from,to)构成新数组,并返回新数组。

int[] arr={1,2,3,4,5,6,7};
int[] arr1 = Arrays.copyOf(arr, arr.length);
for (int i = 0; i < arr1.length; i++) {
   System.out.print(arr1[i]+"\t"); // 1	2	3	4	5	6	7
}
System.out.println();

int[] arr2 = Arrays.copyOfRange(arr, 2, arr.length);
for (int i = 0; i < arr2.length; i++) {
    System.out.print(arr2[i]+"\t"); // 3	4	5	6	7
}

(5)比较两个数组是否相等:

①static boolean equals(int[] a, int[] a2) :比较两个数组的长度、元素是否完 全相同 ;②static boolean equals(Object[] a,Object[] a2):比较两个数组的长度、元素 是否完全相 

int[] arr={1,2,3,4,5,6,7};
int[] arr1={1,2,3,4,5,6,7};
int[] arr2={7,2,3,4,5,6,7};
boolean b1 = Arrays.equals(arr, arr1);
System.out.println(b1); // true
boolean b2 = Arrays.equals(arr, arr2);
System.out.println(b2); // false

(6)填充数组:

①static void fill(int[] a, int val) :用 val 值填充整个 a 数组

②static void fill(Object[] a,Object val):用 val 对象填充整个 a 数组

③static void fill(int[] a, int fromIndex, int toIndex, int val):将 a 数组 [fromIndex,toIndex)部分填充为 val 值

④static void fill(Object[] a, int fromIndex, int toIndex, Object val) :将 a 数组 [fromIndex,toIndex)部分填充为 val 对象文章来源地址https://www.toymoban.com/news/detail-619894.html

int[] arr={1,2,3,4,5,6,7};
Arrays.fill(arr,6);
for (int i = 0; i < arr.length; i++) {
    System.out.print(arr[i]+"\t"); // 6	6	6	6	6	6	6
}
arr=new int[]{1,2,3,4,5,6,7};
Arrays.fill(arr,2,5,8);
for (int i = 0; i < arr.length; i++) {
    System.out.print(arr[i]+"\t"); // 1	2	8	8	8	6	7
}

到了这里,关于JavaSE进阶 | 二维数组的定义和使用、查找和排序算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVASE---数组的定义与使用

    数组是具有相同类型元素的集合,在内存中连续存储。 1. 数组中存放的元素其类型相同 2. 数组的空间是连在一起的 3. 每个空间有自己的编号,起始位置的编号为0,即数组的下标 数组的创建 T代表每个元素的类型 N代表元素的个数/数组长度 数组的初始化 数组的初始化主要分

    2024年02月11日
    浏览(25)
  • 【javaSE】 数组的定义与使用

    目录 数组的基本概念 为什么要使用数组 什么是数组 数组的创建及初始化 数组的创建 数组的初始化 动态初始化 静态初始化  注意事项 数组的使用 数组中元素访问 注意事项 遍历数组 数组是引用类型 初识JVM的内存分布 基本类型变量与引用类型变量的区别 再谈引用变量 ​

    2024年02月15日
    浏览(26)
  • 【第43天】sort 的复杂运用 | 对二维数组与结构体实现自定义排序

    本文已收录于专栏 🌸《Java入门一百练》🌸

    2024年01月17日
    浏览(24)
  • 【JAVASE】学习数组的定义与使用

    ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页: 再无B~U~G-CSDN博客 目标: 1. 理解数组基本概念 2. 掌握数组的基本用法 3. 数组与方法互操作 4. 熟练掌握数组相关的常见问题和代码 数组:可以看成是 相同类型元素的一个集合 。

    2024年04月15日
    浏览(19)
  • 【JavaSE】一维数组和二维数组详解

    欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 一维数组 基本语法 初始化 遍历和打印 数组是引用型变量 基本类型变量与引用类型变量的区别 null 数组传参和返回 总结 二维数组 基本语法 初始化 遍历和打印 数组:可以看成是相同类型元素的

    2024年04月09日
    浏览(34)
  • JavaSE核心基础-二维数组-笔记

    1.二维数组概述 所谓二维数组就是数组中的数组,它的定义格式和一维数组很像。可以保存更多同类型的数据。二维数组的每一个元素是一个一维数组。 2. 二维数组定义的三种格式以及使用   1)格式1(动态初始化): int[][] arr = new int [3][2] ; 定义了名称为arr的二维数组,二

    2024年01月24日
    浏览(23)
  • 「优选算法刷题」:在排序数组中查找元素的第一个和最后个位置

    给你一个按照非递减顺序排列的整数数组  nums ,和一个目标值  target 。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值  target ,返回  [-1, -1] 。 你必须设计并实现时间复杂度为  O(log n)  的算法解决此问题。 示例 1: 示例 2: 示例 3: 二分

    2024年01月22日
    浏览(32)
  • JavaSE基础50题:25. 查找数组中指定元素(顺序查找)

    给定一个数组,再给定一个元素,找出该元素在数组中的位置。 【概述】 一个一个找,比较慢。 想要快一点的方法,可以使用二分查找,在后续《JavaSE基础50题》专栏中27题中详细讲解。 【代码】 【输出结果】

    2024年02月04日
    浏览(34)
  • 【算法Hot100系列】在排序数组中查找元素的第一个和最后一个位置

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月02日
    浏览(39)
  • 【JavaSE】多图解,保姆级详细讲解数组、二维数组--建议收藏

    🌱博主简介:是瑶瑶子啦,一名大一计科生,目前在努力学习JavaSE。热爱写博客~正在努力成为一个厉害的开发程序媛! 📜所属专栏:爪洼岛冒险记【从小白到大佬之路】 ✈往期博文回顾: 【爪洼岛冒险记】第4站 🕵️‍♂️近期目标:成为千粉小博主。 🙇‍♀️写博客理

    2024年01月16日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包