Java数组06:冒泡排序 & 选择 排序 & 二分法查找

一、冒泡排序算法

冒泡排序算法思路:

  • 参与比较的数据:9 8 10 7 6 0 11
    ——第1次循环:
    8 9 10 7 6 0 11 (第1次比较:交换)
    8 9 10 7 6 0 11 (第2次比较:不交换)
    8 9 7 10 6 0 11 (第3次比较:交换)
    8 9 7 6 10 0 11 (第4次比较:交换)
    8 9 7 6 0 10 11 (第5次比较:交换)
    8 9 7 6 0 10 11 (第6次比较:不交换)
    最终冒出的最大数据在右边:11
  • 参与比较的数据:8 9 7 6 0 10
    ——第2次循环:
    8 9 7 6 0 10(第1次比较:不交换)
    8 7 9 6 0 10(第2次比较:交换)
    8 7 6 9 0 10(第3次比较:交换)
    8 7 6 0 9 10(第4次比较:交换)
    8 7 6 0 9 10(第5次比较:不交换)
  • 参与比较的数据:8 7 6 0 9
    ——第3次循环:
    7 8 6 0 9(第1次比较:交换)
    7 6 8 0 9(第2次比较:交换)
    7 6 0 8 9(第3次比较:交换)
    7 6 0 8 9(第4次比较:不交换)
  • 参与比较的数据:7 6 0 8
    ——第4次循环:
    6 7 0 8(第1次比较:交换)
    6 0 7 8(第2次比较:交换)
    6 0 7 8(第3次比较:不交换)
  • 参与比较的数据:6 0 7
    ——第5次循环:
    0 6 7(第1次比较:交换)
    0 6 7(第2次比较:不交换)
  • 参与比较的数据:0 6
    ——第6次循环:
    0 6 (第1次比较:不交换)
public class BubbleSort {
    public static void main(String[] args) {
    
        int[] arr = {9, 8, 10, 7, 6, 0, 11};
//        比较次数
        int count1 = 0;
//        交换次数
        int count2 = 0;
        //比较次数(比较次数为arr.length-1,每次比较得出最大元素)
        for (int i = 0; i < arr.length - 1; i++) {
            boolean flag = false;//通过flag标识位减少没有意义的比较
            
            //比较的元素个数(比较次数+1,比较的元素个数-1)
            for (int j = 0; j < arr.length - 1 - i; j++) {
                count1++;
                //相邻元素判断,如果前面元素大于后面元素,互换位置
                if (arr[j] > arr[j + 1]) {
                    count2++;
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = true;
                }
            }
            //flag还是false,则上面相邻元素判断前面都是小于后面,则证明后面不需要再互换位置了,退出循环
            if (flag == false) {
                break;
            }
        }
        System.out.println(count1);//比较次数:21
        System.out.println(count2);//替换次数:13
        System.out.println(Arrays.toString(arr));//[0, 6, 7, 8, 9, 10, 11]
    }
}

二、选择排序算法

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

选择排序算法思路:

  • 参与比较的数据:9 8 10 7 6 0 11 (这一堆参加比较的数据中最左边的元素下标是0)
    ——第1次循环之后的结果是:
    08 10 7 6 911
  • 参与比较的数据:8 10 7 6 9 11(这一堆参加比较的数据中最左边的元素下标是1)
    ——第2次循环之后的结果是:
    610 7 89 11
  • 参与比较的数据:10 7 8 9 11 (这一堆参加比较的数据中最左边的元素下标是2)
    ——第3次循环之后的结果是:
    7 108 9 11
  • 参与比较的数据:10 8 9 11(这一堆参加比较的数据中最左边的元素下标是3)
    ——第4次循环之后的结果是:
    8 109 11
  • 参与比较的数据:10 9 11(这一堆参加比较的数据中最左边的元素下标是4)
    ——第5次循环之后的结果是:
    9 1011
  • 参与比较的数据:10 11(这一堆参加比较的数据中最左边的元素下标是5)
    ——第6次循环之后的结果是:
    10 11
public class SelectSort {
    public static void main(String[] args) {
        
        int[] arr = {9, 8, 10, 7, 6, 0, 11};
        //        比较次数
        int count1 = 0;
        //        交换次数
        int count2 = 0;

        for (int i = 0; i < arr.length - 1; i++) {
            //最小数的下标
            int min = i;
            for (int j = i+1; j < arr.length; j++) {
                count1++;
                if (arr[min] > arr[j]) {
                    min = j;//求得最小数的下标
                }
            }
            //如果下标i不是最小数的下标,则数组下标i对应的数值替换为最小的值
            if (i != min) {
                count2++;
                int temp = arr[i];
                arr[i] = arr[min];
                arr[min] = temp;
            }
        }
        System.out.println(count1);//比较次数:21
        System.out.println(count2);//替换次数:5
        System.out.println(Arrays.toString(arr));//[0, 6, 7, 8, 9, 10, 11]
    }
}

三、二分法查找算法(折半查找)

第一:二分法查找建立在排序的基础之上。
第二:二分法查找效率要高于“一个挨着一个”的这种查找方式。

二分法查找思路:
10(下标为0) 23 56 89 100 111 222 235 500 600(下标为9) arr数组
目标:找出 89 的下标


——(0 + 9) / 2 --> 4(中间元素的下标)
arr[4]这个元素就是中间元素:arr[4]是 100
100 > 89
说明被查找的元素在100的左边。
那么此时结束元素下标变成:4 - 1


——(0 + 3) / 2 --> 1(中间元素的下标)
arr[1] 对应的是:23
23 < 89
说明被查找的元素在23的右边。
那么此时开始元素下标变成:1 + 1


——(2 + 3) / 2 --> 2(中间元素的下标)
arr[2] --> 56
56 < 89
说明被查找的元素在56的右边。
那么此时开始元素下标变成:2 + 1


——(3 + 3) / 2 --> 3(中间元素的下标)
arr[3]是89,正好和89相等,此时找到了。

public class ArraySearch {
    public static void main(String[] args) {
        //创建一个数组
        //10(```下标为0```) 23 56 89 100 111 222 235 500 600(```下标为9```)
        int[] arr = {10, 23, 56, 89, 100, 111, 222, 235, 500, 600};
        //在数组arr查找 89 元素的下标位置
        int index = binarySearch1(arr, 89);
        System.out.println(index==-1?"给定数组没有要查找的元素":"指定元素在给定数组中的下标位置为"+index);
        //指定元素在给定数组中的下标位置为3
    }

    /**
     * 从给定数组中查找指定元素的下标
     * @param arr 给定数组
     * @param i 指定元素
     * @return 返回-1则为此数组没有此元素,返回大于等于0的数则为指定元素在给定数组中的下标
     */
    private static int binarySearch1(int[] arr, int i) {
//        开始下标
        int begin = 0;
//        结束下标
        int end = arr.length - 1;

//        循环判断指定元素是否比中间元素大还是小,直到找到中间元素为指定元素或未找到该元素结束循环
        while (begin <= end) {
            //        中间元素下标
            int mid = (begin + end) / 2;
//        判断指定元素比中间元素大还是小
            if (i == arr[mid]) {
//                如果相等中间元素,则返回指定元素在该数组的下标位置
                return mid;
            } else if (i > arr[mid]) {
//                如果大于中间元素,则在中间元素的右侧,开始下标改为中间元素下标+1
                begin = mid + 1;
            } else {
//                如果小于中间元素,则在中间元素的左侧,结束下标改为中间元素下标-1
                end = mid - 1;
            }
        }
        return -1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值