今日战果:数组进阶


一、数组排序[面试|笔试]

排序: 不是从小到大输出,而是将数组改变原有顺序

十大排序算法

  • 冒泡排序,选择排序,插入排序
  • 快速排序,堆排序,希尔排序,归并排序
  • 桶排序,计数排序,基排序

今天先简述冒泡排序和选择排序

1.1 冒泡排序

冒泡就是指像泡泡一样,将大的泡泡(数据)依次往上(后)浮(移)动…

思路:

  • 相邻两个依次比较大小,发现大的交换位置,将大的放后面
    在这里插入图片描述
 public static void bubble() {
        // -1,最后一趟不用比较
        int[] arr = {6,5,7,4,3,2,1};
        for (int i = 0; i < arr.length - 1; i++) {
            // -1,是为了防止越界.-i是为了每趟内少比较i次
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j+1]) {
                    int temp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                }
            }
        }

       // 遍历排序后的数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

image-20240522111952206

1.2 选择排序

选择排序,将数组分成两个区间,一个是排过序的区间,一个是未排序的区间

在未排序的区间内,从第一个开始依次找最小的数据,并记录其位置(下标),找完后将最小数据与第一个交换
在这里插入图片描述

  public static void choose() {
        int[] arr = {9,6,5,7,4,8,3,2,10,1};
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i; //第一次先将0作为最小数值的下标
             /*
             内层循环是为了找到最小值的下标
             */
            for (int j = i; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) { //比较大小
                    minIndex = j; //记录最小值下标
                }
            }
			/*
			找到每趟最小值,交换数据
			*/
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }

        // 遍历排序后的数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

二、查找算法

二分查找算法

查询数组中是否存在某个指定的元素(根据元素找下标,找到就返回元素下标,找不到返回-1)

二分查找也叫折半查找,二分查找的前提是有序数组

	private static void bearySearch(int[] arr, int e) {
        int left = 0; // 左边界
        int right = arr.length - 1; // 右边界
        int mid = (left + right) / 2;// 中间值

        while(left <= right){
            if (e > arr[mid]) { // 要找的数在右侧
                left = mid + 1; // 左边界缩小
            } else if (e < arr[mid]) { // 要找的数在左侧
                right = mid - 1;  // 有边界缩小
            } else {
                System.out.println(mid );
                return;// 找到结束
            }
            mid = (left + right) / 2;// 缩小边界后,中间值重新计算
        }
        System.out.println(-1 );// 找不到返回-1
    }

三、数组拷贝

数组拷贝就是将一个数组的元素赋值到另外一个数组中

3.1 手动拷贝

 	/**
     * 手动实现数组拷贝
     */
    private static void copyArrayByMyself() {
        // 现有一个数组,根据这个数组创建一个一样的数组
        int[] arr1 = {1,2,3,4,5};

        // 创建新数组
        int[] arr2 = new int[arr1.length];
        printArr(arr2);// 遍历数组的方法,用于查看数组
        // 拷贝
        for (int i = 0; i < arr1.length; i++) {
            arr2[i] = arr1[i];
        }
        printArr(arr2);// 遍历数组的方法,用于查看数组
    }
	/**
     * 遍历数组的工具方法
     */
    public static void printArr(int[] arr) {
        String s = "[";
        for (int i = 0; i < arr.length; i++) {
            s += arr[i];
            if (i == arr.length - 1) {
                s += "]";
            } else {
                s +=",";
            }
        }
        System.out.println(s );
    }

练习: 数组合并


    /*
     * {1,2,5,8,9}{1,3,0}---->{1,2,5,8,9,1,3,0} (合并)
     */
    public static void concat() {
        int[] a1 = {1,2,5,8,9};
        int[] a2 = {1,3,0};
        // 创建第3个数组,存储最终合并后的结果
        int[] a3 = new int[a1.length + a2.length];
        printArr(a3);// 遍历数组的方法,用于查看数组

        // 拷贝a1到a3
        // for (int i = 0; i < a1.length; i++) {
        //     a3[i] = a1[i];
        // }

        // 拷贝a2到a3
        // for (int i = 0; i < a2.length; i++) {
        //     a3[a1.length+i] = a2[i];
        // }

        for (int i = 0; i < a3.length; i++) {
            if (i < a1.length){
                a3[i] = a1[i];
            } else {
                a3[i] = a2[i-a1.length];
            }
        }

        printArr(a3);// 遍历数组的方法,用于查看数组
    }

3.2 System.arraycopy

System是java中自己提供好的一个类,其中有个方法arraycopy可以完成数组拷贝

以下是jdk中的System.arraycopy的源码,以及参数注释

 /* @param      src      the source array.    源数组(从哪个数组拷贝)
 * @param      srcPos   starting position in the source array.   从源数组起始拷贝的位置
 * @param      dest     the destination array.  目标数组(拷贝到哪个数组)
 * @param      destPos  starting position in the destination data.  放到目标数组哪个位置
 * @param      length   the number of array elements to be copied.  长度,拷贝多少个
 */
public static native void arraycopy(Object src,  
                                    int  srcPos,
                                    Object dest, 
                                    int destPos,
                                    int length);

下面演示如何使用

    /**
     * 使用System类中的方法完成数组拷贝
     */
    public static void copyArrayBySystem(){
        // 需求,拷贝下面数组中的2,5,8到
        // 新数组的第2,3,4的位置上,即[0,2,5,8,0]
        int[] arr = {1,2,5,8,9};

        // 创建一个数组,准备存储拷贝后的数据
        int[] arr2 = new int[arr.length];
        printArr(arr2);// 遍历数组的方法,用于查看数组

        /**
         * 参数1: 源数组(从哪个数组拷贝)
         * 参数2: 从源数组起始拷贝的位置
         * 参数3: 目标数组(拷贝到哪个数组)
         * 参数4: 放到目标数组哪个位置
         * 参数5: 长度,拷贝多少个
         */
        System.arraycopy(arr,1,arr2,1,3);
        printArr(arr2);// 遍历数组的方法,用于查看数组
    }

3.3 Arrays.copyOf

Arrays是java中操作数组的工具类,类中提供了一些操作数组的方法,其中copyOf方法,可以帮助我们创建新数组并拷贝

 	/**
     * 使用Arrays.copy完成拷贝
     */
    public static void copyArrayByArrays() {
        int[] arr = {1,2,5,8,0};

        int[] arr2 = Arrays.copyOf(arr,10);
        printArr(arr2);// 遍历数组的方法,用于查看数组
    }

参考阅读,Arrays.copyOf的源码

 /* @param original the array to be copied
 * @param newLength the length of the copy to be returned
  */
 public static int[] copyOf(int[] original, int newLength) {
     int[] copy = new int[newLength];
     System.arraycopy(original, 0, copy, 0,
                      Math.min(original.length, newLength));
     return copy;
 }

四、数组扩容

数组长度不能改变!!!

这里的扩容,是假的扩容,其实是重新创建了一个更大的数组,将原来的数据拷贝到大数组里面,最后将这个大数组返回给你继续使用`

    public static void main(String[] args) {
        int[] arr = {1,2,5,8,3};
        printArr(arr);

        // 数组扩容
        arr = changeSize(arr);

        printArr(arr);
    }

    /**
     * 改变数组大小的方法(扩容),一般是2倍
     * @param arr,要扩容的数组
     * @return 返回的大数组
     */
    private static int[] changeSize(int[] arr) {

        // 1创建大数组
        int[] bigArr = new int[2 * arr.length];

        // 2拷贝
        System.arraycopy(arr,0,bigArr,0,arr.length);

        // 3返回大数组
        return bigArr;
    }

image-20240522164532073


五、Arrays[常用]

Arrays是java中提供好的,操作数组的工具类,类中提供了一些操作数组的方法

  • Arrays.copyOf() 拷贝数组
  • Arrays.sort() 数组排序
  • Arrays.toString() 将数组以字符串返回[1,2,3]
  • Arrays.binarySearch() 二分查找算法
public static void main(String[] args) {
        int[] arr = {5,3,2,1,4};

        // String s = Arrays.toString(arr);
        // System.out.println(s );

        /**
         * 将数组以字符串[1,2,3,4]形式返回
         */
        System.out.println(Arrays.toString(arr) );

        /**
         * sort,将数组排序,只能升序
         */
        Arrays.sort(arr);

        System.out.println(Arrays.toString(arr) );

        /**
         * 二分查找算法,根据元素找下标
         * -----
         * 目的是判断数组中是否包含该元素
         * 如果返回值是负数,说明没找到,即不包含
         * 返回值是>=0 ,就说明找到了,即包含该元素
         */
        int i = Arrays.binarySearch(arr, 2);
        System.out.println(i );
    }

最后

如果感觉有收获的话,点个赞 👍🏻 吧。
❤️❤️❤️本人菜鸟修行期,如有错误,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值