基础排序算法之——冒泡排序 && 二分查找 && 选择排序 && 插入排序

在这里插入图片描述
注:鸡尾酒排序是双向冒泡排序,将在后面的blog中进行更新。


前言

各位小伙伴们,本次博客主要来与大家共同学习四大排序算法是如何实现的?你想不想了解一下冒泡是如何大数沉底的呢?选择是如何小数上浮的呢?插入算法是如何在有序数组中见缝插针的呢?如何实现高效率二分查找呢?快快快,接着往下读…


一、冒泡排序

在这里插入图片描述

日常想法:哈哈哈,看到这个图你有没有放弃人生的感觉,别急坚持一下,你就能弄懂冒泡泡的原理了。

1、算法实现
核心思想:通过一趟遍历将最大的数,冒到最后。我们将交换函数进行封装后再多次使用,只需要调用它就可以了。代码中将用j控制趟数,i控制每一次遍历的下标,这里因为可以确定遍历一趟肯定可以将该趟中的最大值固定在最后,遍历n趟可以固定n个数,这n个数不用在进行比较,所以i的约束条件是i<arr.length-1-i。
(要-1是为了防止下标越界)

public static void swap(int[] arr,int index1,int index2){
        int temp=arr[index1];
        arr[index1]=arr[index2];
        arr[index2]=temp;
    }
    public static void bubbleSort(int[] arr){
        boolean flag=false;
        for(int j=0;j<arr.length;j++) {//j控制趟数
            flag=false;//每一趟都是一个新的flag

            for (int i= 0; i< arr.length-1-j; i++) {  //要-1,防止i+1下标越界(每一趟操作思路)
                if (arr[i] > arr[i + 1]) {
                    flag=true;
                    swap(arr, i, i + 1);
                }
            }
            if(flag){
                continue;
            }else{
                return;  //break;跳出当前大循环(第一层循环)
            }

        }
    }

代码中我们进行了优化,设置了标记遍历,是为了避免数组已经有序了,还在重复比较遍历的情况。
2、测试代码

 public static void main(String[] args) {
        int[] arr={2,3,1,6,4,7};
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));
    }

3、结果展示
在这里插入图片描述

二、二分查找

1、算法实现
需要注意的问题:
(1)可能越界(L+R)/2 ——>(R-L)/2+L/2
(2)因为计算机中采用位运算,所以我们将/2操作改写为右移>>>,这样可以加快程序的运行速度。但需要注意运算符的优先级,给它加上小括号哦。

//TODO:二分查找(注意要为有序数组)
    // 时间复杂度O(log2^n),空间复杂度O(1)没有开辟新的空间,与问题规模无关
    public static int binarySearch(int arr[],int value){
        int left=0;
        int right=arr.length-1;
        while(left<=right){
            int mid=((right-left)>>>1)+left;  //优化:1)越界问题  2)位运算优化,注意优先级
            if(arr[mid]==value){
                return mid;
            }else if(arr[mid]<value){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return -1;//没有找到的情况
    }

2、测试代码

 public static void main(String[] args) {
        int[]arr={3,4,6,8,9};
        int a=binarySearch(arr,9);
        System.out.println("该值所对应的下标为:"+a+" 值的大小是:"+arr[a]);
    }

3、结果展示
在这里插入图片描述

三、选择排序

1、算法实现
可以将它与冒泡排序进行对比,冒泡排序是将大数想下沉,而选择排序是将小数向上浮。

//TODO:选择排序——>与冒泡相反,将小数往上冒(i控制有序序列,j在当前i以后的序列中找最小值)
    public static void swap(int[]arr,int index1,int index2){
        int temp=arr[index1];
        arr[index1]=arr[index2];
        arr[index2]=temp;
    }
    public static void selectSort(int[]arr){
        if(arr==null||arr.length==0){
            return;
        }
        int mindex;
        for (int i=0;i<arr.length;i++){
            //找最小值(假设起始位置为最小值)
            mindex=i;
            for(int j=i;j<arr.length;j++){
                if(arr[mindex]>arr[j]){
                    mindex=j;
                }
            }
            swap(arr,i,mindex);//最小元素和待排序相对的首位进行交换
        }
    }

2、测试代码

public static void main(String[] args) {
        int[]arr={4,3,1,8,9};
        selectSort(arr);
        System.out.println(Arrays.toString(arr));
    }

3、结果展示
在这里插入图片描述

对于这个算法的实现,我们也可以进行以下的优化:
优化思想:设置begin=0,end=arr.length-1,maxindex,mindex先开始存入arr[end]和arr[begin]的value,通过使用z进行数组遍历,当arr[z]>arr[maxind],将此时z赋给end,当arr[z]<arr[minindex]。当第一个位置和最后位置放上整个数组的最大值和最小值后,begin++,end–,然后再在无序数列中寻找最大值和最小值。(注意条件begin<end)

    public static void selectSort(int[]arr){
        if(arr==null||arr.length==0){
            return;
        }
        int begin=0;
        int end=arr.length-1;
        int maxindex=arr[begin];
        int minindex=arr[begin];
        while(begin<end){
        for(int z=begin;z<end;z++){
            if(arr[z]>arr[maxindex]){
                maxindex=z;
            }
            if(arr[z]<arr[minindex]){
                minindex=z;
            }
        }
        swap(arr,minindex,begin);
        swap(arr,maxindex,end);
        begin++;
        end--;
    }
    }

总结:
这种优化方法并没有降低选择排序的时间复杂度,只是减少了数组的遍历次数。

四、插入排序

1、算法实现
核心将整个数组看成两个部分组成,一边是有序的数组,一边是无序数组,通过遍历无序数组,将无序数组的值插入到有序数组的合适位置。

   public static void insertSort(int[]arr){
        if (arr==null||arr.length==0){
            return;
        }
        int j=0;
        for(int i=0;i<arr.length-1;i++){
            int temp=arr[i+1];
            for(j=i;j>=0;j--){
                if(arr[j]>temp){
                    arr[j+1]=arr[j];
                }else{
                    arr[j+1]=temp;
                    break;
                }
            }
            arr[j+1]=temp;
        }
    }

2、测试代码

   public static void main(String[] args) {
        int[]arr={4,3,1,8,9};
        insertSort(arr);
        System.out.println(Arrays.toString(arr));
    }

3、结果展示
在这里插入图片描述

总结

哈哈哈,恭喜你!历经千辛万苦看的这里了,相信你已经对这四种算法了如指掌了叭,期待我们的下次相见哈!

算法时间复杂度
冒泡排序O(n^2)
二分查找O(log2^n)
选择排序O(n^2)
插入排序O(n^2)
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值