排序算法-冒泡,插入,选择排序

冒泡排序

算法原理(从小到大排序为例):

  1. 将数组分成两部分,左边部分为已排序部分,右边部分为未排序部分
  2. 从未排序部分的右侧开始比较遍历,相邻两个元素比较,保证小元素在前,即如果num[j]>num[j+1],就做元素交换,否则不交换
  3. 交换到左右两部分的边界处,右边第一个元素即为右边部分最小元素,左边最后一个元素即为左边部分最大元素,由于左边部分是右边部分每次从小到大冒泡排序出来的,所以此时左边部分加上右边第一个元素为有序部分,有序部分的数组下标加一。

在这里插入图片描述
图片来源:https://blog.youkuaiyun.com/pzhtpf/article/details/7560294

空间复杂度O(1),时间复杂度O(n^2),属于稳定排序
代码如下:

/**
     * 冒泡排序:从小到大排序,从后往前遍历
     * space:O(1)
     * time:O(n^2)
     * 稳定排序
     * @param nums
     */
    public static void bubbleSort(int[] nums){
        for(int i =0;i<nums.length;i++){
            for(int j=nums.length-1;j>i;j--){
                if(nums[j]<nums[j-1]) swap(nums,j,j-1);
            }
        }
    }

    private static void swap(int[] num,int i,int j){
        int tmp = num[i];
        num[i]= num[j];
        num[j]= tmp;
    }

插入排序

算法原理(从小到大排序为例):

  1. 将数组分成两部分,左边部分为已排序部分,右边部分为未排序部分
  2. 将未排序部分的第一个元素选为比较元素,在已排序部分进行比较遍历,从右往左,从大到小比较遍历,每次比较都将比较过的元素后移一位,直至 比较元素大于等于遍历元素,此时将比较元素加入数组

在这里插入图片描述
图片来源:极客时间,《数据结构与算法之美》12章

空间复杂度:O(1),时间复杂度:O(n^2),属于稳定排序
代码如下:

/**
     * 插入排序:从小到大排序,从后往前遍历
     * space:O(1)
     * time:O(n^2)
     * 稳定排序
     * @param nums
     */
    public static void insertionSort(int[] nums){
        for(int i =1;i<nums.length;i++){
            int j=i,tmp=nums[j--];//i表示无序部分的第一个元素下标,j--表示有序部分最后一个元素,从j--开始比较遍历
            for(;j>=0;j--){
                if(tmp<nums[j]){
                    nums[j+1] = nums[j];
                }else{
                    break;//在有序部分找到对应位置,插入,退出循环
                }
            }
            nums[j+1] = tmp;//要么是遍历到头,要么是找到位置
        }
    }

在真实的使用中,插入排序比冒泡排序使用更多,因为在比较遍历时,插入排序移动元素比冒泡排序更少,而真实使用场景中,排序数量一般不大,10,100,1000,复杂度分析中忽略的低阶,系数,常数得考虑到。后面的选择排序,本身是不稳定算法,先天就落了下乘

//冒泡3次
private static void swap(int[] num,int i,int j){
        int tmp = num[i];
        num[i]= num[j];
        num[j]= tmp;
    }

//插入1次
nums[j+1] = nums[j];

选择排序

算法原理(从小到大排序为例):

  1. 将数组分成两部分,左边部分为已排序部分,右边部分为未排序部分
  2. 从右侧未排序部分选择最小的元素,和未排序部分的第一个元素交换位置

空间复杂度:O(1),时间复杂度:最好/最坏/平均 都是 O(n^2),属于不稳定排序
如数组:5,4,5,2 在选择排序时,2与第一个5交换位置,相对顺序就被破坏了

代码如下:

/**
     * 选择排序:从小到大排序
     * space:O(1)
     * time:O(n^2)
     * 不稳定排序
     * @param nums
     */
    public static void selectionSort(int[] nums){
        for(int i =0;i<nums.length;i++){
            int minIndex = i;
            for(int j=i+1;j<nums.length;j++){
                if(nums[j]<nums[minIndex]){
                    minIndex = j;
                }
            }
            swap(nums,i,minIndex);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值