十大排序算法(附动态图解)- Java版

十大排序算法性能对比

 稳定性:例如[a,b],a和b是相等的,当排完序后a和b的位置互换了就说明不稳定,没有互换就说明稳定。
image-20220328161706745

前言

 算法都有优劣,了解算法的性能才能在实践中选择更好的算法,所以了解算法性能十分的必要。

 在性能上对比归并排序、快速排序、堆排序是相对来说比较好的排序算法,可以重点理解下这些算法;希尔排序相对于以上三个并不是最好,但也可以重点学习理解,面试过程中考察点突发奇想,冒泡选择插入也说不定会考察。

扩展

 在JDK中Array.sort()排序方法中,在数组长度小于286时,使用的是快速排序,而在数组长度小于47时使用的是插入排序。在JDK8中还有一点就是,在数组长度小于286大于47,并且数组具有一定结构,则使用归并排序。

一、选择排序

 算法描述:

  1、将第一位当成最小值,记录值和下标,用最小值向右进行逐个比较,查找是否有更小的,有则更新最小的值和下标。

  2、判断最小值下标是否变动,变动则交换位置,将新的最小值位置赋值为旧的最小值,旧的赋值为新的最小值。

 静态图解
在这里插入图片描述
 动图图解

在这里插入图片描述

 代码部分

/**
* 选择排序:
*  外层循环的作用:
*      选择排序执行的次数
*  内层循环的作用:
*      将第一位当成最小值,记录值和下标,用最小值向右进行逐个比较,查找是否有更小的,有则更新最小的值和下标。
*  判断语句的作用:
*      判断最小值下标是否变动,变动则交换位置,将新的最小值位置赋值为旧的最小值,旧的赋值为新的最小值。
*/
@Test
public void Test() {
   
    int[] arr = new int[]{
   -12, -55, -23, 43, 24, 34, 12};
    SelectSortFun(arr);
    Arrays.stream(arr).forEach(i -> System.out.print(i + " "));
}

public void SelectSortFun(int[] arr) {
   
    for (int i = 0; i < arr.length - 1; i++) {
    // 选择排序执行的次数
        int min = arr[i];
        int minIndex = i;
        for (int j = i; j < arr.length; j++) {
    // 每次遍历确定最左边的一位最小值,所以从i开始。
            if (min > arr[j+1]) {
   
                min = arr[j+1];
                minIndex = j+1;
            }
        }
        if (i != minIndex) {
           // 最小值有变动,不是原来的那个,则交换。
            arr[minIndex] = arr[i]; // 查找到的最小值下标赋值为下标i的数
            arr[i] = min;           // 下标i赋值为最小值
        }
    }
}

二、冒泡排序

 算法描述:两两进行比较,从左开始,5大于2则交换,5大于1则交换,如果有比5大的,则将自身下标设置为更大的值的下标,继续向后比较,直到自身为最大,则确定了数组最右边为第一个最大值,同理逐个确定,直到只剩一个则完成排序。

 静态图解

在这里插入图片描述

 动图图解

在这里插入图片描述
 代码部分

    @Test
    public void Test() {
   
        int[] arr = new int[]{
   -12, -55, -23, 43, 24, 34, 12};
        BubbleSortFun(arr);
        Arrays.stream(arr).forEach(i -> System.out.print(i + " "));
    }

    public void BubbleSortFun(int[] arr) {
   
        boolean flag = true; //优化有序数组多次进行循环,当遇到没交换位置的情况则提前终止循环
        for (int i = 0; i < arr.length - 1; i++) {
    // 冒泡的次数
            for (int j = 0; j < arr.length - i - 1; j++) {
    // 每次冒泡确定了最后一位数字,所以减i,防止再次遍历后面的数浪费时间。
                if (arr[j] > arr[j + 1]) {
   
                    flag = false; // 进去了说明有无序数组则不跳过继续循环,没进去才跳过停止循环
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (flag) {
   
                break;
            }
        }
    }

三、插入排序

 算法描述:认为第一个元素已经排序,从第二个元素开始(也就是下标1开始),取出下一个元素,向左扫描,如果取出的元素小于向左扫描的元素,则将扫描到的元素向右移,将取出的元素移动到比他更小的值的前一位。

 动图图解

在这里插入图片描述

 代码部分

    @Test
    public void Test() {
   
        int[] arr = new int[]{
   -12, -55, -23, 43, 24, 34, 12};
        insertionSort(arr);
        Arrays.stream(arr).forEach(i -> System.out.print(i + " "));
    }

    public int[] insertionSort(int[] arr) {
   
        int preIndex,current; // pre是下一个需要排序的元素,cur是当前元素的备份值
        for (int i = 1; i < arr.length; i++) {
   
            preIndex = i - 1; // 移动的下标
            current = arr[i]; // 记录被覆盖的值
            while (preIndex >= 0 && arr[preIndex] > current) {
    // 
                arr[preIndex + 1] = 
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值