Java中常见的算法和Arrays工具类

一、常见的算法

1.1 冒泡排序

概念:冒泡排序是一种排序算法,(以升序排序为例)原理是每次通过相邻的两个元素比较,找出较大的那个元素,放到两元素之中较后的元素位置上,即如果两个元素前面的元素大于后面的那个元素,就交换两个元素的位置。每次遍历到未实现排序的元素,每次获得一个较大值放到数组的后面,以此反复,在实现n-1(假设有n个元素)次迭代后,找出了n-1个较大值完成升序排序,因为每一次找出一个较大值放在数组的最后,类似水中的冒泡,故称为冒泡排序。

public class Test {
    public static void main(String[] args) {
        int arr[] = {12, 23, 9, 34, 22, 45};
        int[] newArr = getArr(arr);
        System.out.println(Arrays.toString(newArr));
    }
    public static int[] getArr(int arr[]){
        if(arr == null || arr.length ==0){
            return null;
        }
        // 冒泡排序确定要实现n-1次的迭代,即要找出n-1个较大值
        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]){
                    // 符合条件就交换位置
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        return arr;
    }
}

在这里插入图片描述

1.2 选择排序

选择排序是一种排序算法,(以升序排序为例)假设数组中有n个元素,要进行n-1次迭代,每一次迭代找出一个最小值放在未排序元素的最前面,每一次迭代遍历未排序元素,固定未排序元素的第一个元素,让第一个元素依次跟后面的元素比较,如果后面有元素比第一个的值小(符合排序规则)就交换两个元素的位置,下一次继续用第一个元素跟后面未遍历的元素比较,以此每一次迭代就能保证找出未排序元素中的最小值。

public class Test {
    public static void main(String[] args) {
        int arr[] = {44, 33, 22, 11};
        int newArr[] = getArr(arr);
        System.out.println(Arrays.toString(newArr));
    }

    public static int[] getArr(int arr[]) {
        if (arr == null || arr.length == 0) {
            return null;
        }
        for (int i = 0; i < arr.length; i++) {
            // 每一次迭代找出最小的值放在未排序元素的最前面
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }
}

在这里插入图片描述

1.3二分查找

二分查找是确定一个数据结构中是否有某个数据的算法,它默认的条件是升序或降序,每次查找的值只能是一个。它的原理是每次确定可查找序列的头尾值的位置,并通过头尾的位置计算出序列的中间位置,每一次迭代比较目标值和中间值,根据不同情况舍弃另一半序列或者直接找到目标值对应的数据。因为每一次迭代很大概率都要舍弃一半的序列进行查找,所以次算法本称为二分查找。

public class Test {
    public static void main(String[] args) {
        int arr[] = {22, 11, 55, 44, 33};
        int index = getIndex(arr, 22);
        System.out.println("目标数字的下标为:" + index);
    }

    public static int getIndex(int arr[], int target) {
        // 查找前先进行数组的判断
        if(arr == null || arr.length == 0){
           return -1;
        }
        // 二分查找前先进行排序
        Arrays.sort(arr);
        // 进行迭代
        int left = 0; // 头位置下标
        int right = arr.length - 1; // 尾位置下标
        while (left <= right) {
            // 每一次迭代要重新定义中间位置的值
            int middle = (left + right) / 2;
            if (arr[middle] > target) {
                // 说明目标值在序列的左边,舍弃右边的序列,重新定义尾位置的下标
                right = middle - 1; // 因为arr[middle] > target,说明中间位置的值也不是目标值,所以要往左移动一位
            } else if (arr[middle] < target) {
                // 说明目标值在序列的右边,舍弃左边的序列,重新定义头位置的下标
                left = middle + 1; // 因为arr[middle] < target,说明中间位置的值也不是目标值,所以要往右移动一位
            }else {
                return middle; // 这种情况就是中间值等于目标值,所以直接返回中间值的索引
            }
        }
        return -1; // 找不到目标值返回-1
    }
}
  • 在程序开始前,我们对首尾位置的值进行初始化

  • left = 0; right = arr.length-1;

  • middle = (left+right)/2;

  • 第一轮迭代我们对比arr[middle]target的值,发现中间值大于目标值,这样我们就要舍弃右边的序列,重新定义尾位置right的值为middle-1

在这里插入图片描述

  • 第二轮迭代我们确定了首尾的值,并根据其计算出中间的值middle = 0
  • 开始比较arr[middle]target的值,发现两者相同
  • 找到目标值,返回目标值的下标middle,并结束迭代,查询完毕

在这里插入图片描述

二、Arrays工具类

Arrays类其实就是一个工具类,是Java为操作数组提供的类,里面提供了很多API,如toString()、sort()、setAll()等这些常用API,下面我们就演示一下它们的作用

API作用
toString()返回数组的特定形式字符串
copyOfRange(Object arr[], int start, int end)返回一个新数组,复制特定范围的数组内容,包前不包后
copyOf(Object arr[], int length)返回一个新数组,把数组复制进一个指定长度的新数组里面
sort()改变原数组,把基本数据类型和String类型的数组从到大排列
sort()改变原数组让数组按照指定的规则排序
setAll(Object arr[],匿名方法)把数组中的数据进行操作后返回
binarySearch(arr[],int number)前提是数组有序,底层通过二分查找找寻指定数据的索引,找不到就返回-1
public class Test {
    public static void main(String[] args) {
        int arr[] = {55,44,33,22,11};

        // toString() 返回数组的特定形式字符串
        String s = Arrays.toString(arr);
        System.out.println(s);
        System.out.println("--------------------");

        // copyOfRange(Object arr[], int start, int end)
        // 返回一个新数组,复制特定范围的数组内容,包前不包后
        int[] newArr = Arrays.copyOfRange(arr, 2, 4);
        System.out.println(Arrays.toString(newArr));
        System.out.println("--------------------");

        // copyOf(Object arr[], int length)  返回一个新数组,把数组复制进一个指定长度的新数组里面
        int[] newArr2 = Arrays.copyOf(arr, 6);
        System.out.println(Arrays.toString(newArr2));
        System.out.println("--------------------");

        // sort() 改变原数组,把基本数据类型和String类型的数组从到大排列
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println("--------------------");

        // sort(匿名内部类) 一般用于自定义类型的数组
        Student s1 = new Student("乾巧", 19);
        Student s2 = new Student("草加", 23);
        Student s3 = new Student("小樱", 16);
        Student s4 = new Student("五代", 21);
        Student student[] = {s1,s2,s3,s4};
        Arrays.sort(student, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 按照年龄的升序排列
                return o1.getAge()-o2.getAge();
            }
        });
        System.out.println(Arrays.toString(student));
        System.out.println("--------------------");
        // setAll(Object arr[],匿名方法) 把数组中的数据进行操作后返回
        Arrays.setAll(arr, new IntUnaryOperator() {
            @Override
            public int applyAsInt(int operand) {
                return arr[operand]+10;
            }
        });
        System.out.println(Arrays.toString(arr));
        System.out.println("--------------------");

        // binarySearch(arr[],int number) 前提是数组有序,底层通过二分查找找寻指定数据的索引,找不到就返回-1
        int index = Arrays.binarySearch(arr, 43);
        System.out.println("索引为:"+index);
    }
}

补充:sort()方法对于自定义类型的数据进行排序有两种,第一种是让类实现Comparable<?>接口,并重写compareTo(? obj)方法,里面指定比较规则;第二种是传入Comparator接口的实现类对象,里面也是重写compare(? o1,? o2)并指定比较规则

比较规则:总体来说两种重写的方法都会传入两个参数,这两个参数分别是数组里面的相邻的两个元素,方法规定,如果返回的是整数,就交换两个元素的位置
总结:升序–>参数1-参数2-----降序–>参数2-参数1
下面是sort()对于自定义类型数据排序的第二种方法

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值