交换排序详讲:冒泡排序+快速排序(多方法+思路+图解+代码)

文章目录


交换排序


  • 根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置
  • 将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

一.冒泡排序

java 复制代码
    /**
     * 冒泡排序
     * 时间复杂度 n^2
     * 空间复杂度  1
     * @param array
     */
    public static void bubbleSort(int[]array){
        for (int i = 0; i < array.length-1; i++) {//趟数
            boolean flg =false;
            for (int j = 0; j < array.length-1-i; j++) {
                if (array[j]>array[j+1]){
                    swap(array,j,j+1);
                    flg = true;
                }
            }
            if (flg == false){
                return;
            }
        }
    }

1.遍历 i 代表交换的趟数,遍历 j 进行两两交换

2.j < array.length-1-i 是对于趟数的优化,每走一趟,交换就少一次

3.boolean flg =false;当两两交换时,flg变为true

4.进一步优化:如果遍历完,没发生交换,flg还是false,直接返回,排序结束

  • 时间复杂度:O ( N2 )
  • 空间复杂度:O ( 1 )
  • 稳定性:稳定

二.快速排序

  • 二叉树结构的交换排序方法

  • 任取一个待排序元素作为基准值,把序列一分为二,左子序都比基准值小,右子序都比基准值大,左右两边再重复进行

  • 左边找比基准值大的,右边找比基准值小的
1.挖坑法
  • 基准值位置挖一个坑,后面找一个比基准值小的把坑埋上
  • 前面找一个比基准值大的,埋后面的坑
  • 当l==r时,把基准值填入剩下的坑中
  • 左右两边重复进行上述步骤,直到排完为止
  • 左右两边都以同样的方法进行划分,运用递归来实现
java 复制代码
    /**
     * 快速排序 ---挖坑法
     *
     * @param array
     */

    public static void quickSort(int[] array) {
        quick(array, 0, array.length - 1);
    }

    private static void quick(int[] array, int start, int end) {
        if (start >= end) {
            return;//结束条件
            // start == end,说明只剩一个了,是有序的,返回
            //start > end ,说明此时的基准值在开头或者末尾
            //在开头:start不变,end=pivot-1,start > end ,end=-1 没有左树
            //在结尾:end不变,start = pivot+1,start > end,超出索引,没有右树
        }
        //不断递归quick
        int pivot = partition(array, start, end);// 进行排序,划分找到pivot
        //然后递归划分法左边,递归划分的右边
        quick(array, start, pivot - 1);
        quick(array, pivot + 1, end);
    }

    //划分,返回基准值
    private static int partition(int[] array, int left, int right) {
        int tmp = array[left];//挖一个坑,取left位置为基准值
        while (left < right) {
            //在右边找一个比基准值小的把坑填上
            while (left < right && array[right] >= tmp) {//防止越界
                right--;
            }
            array[left] = array[right];//找到比tmp小的数,填坑,

            //在左边找一个比tmp大的值,填到右边的坑
            while (left < right && array[left] <= tmp) {//防止越界
                left++;
            }
            array[right] = array[left];
        }//如果相遇了,退出循环
        array[left] = tmp;//填坑
        return left;
    }
  • 先划分序列,递归左边,然后再递归右边

  • 递归结束条件:

    start == end时,说明只剩一个了,是有序的,返回

    start > end 时 ,说明此时的基准值在开头或者末尾

    如果基准值在开头:start不变,end=pivot-1,start > end ,end=-1 没有左树

    如果基准值在结尾:end不变,start = pivot+1,start > end,超出索引,没有右树


2.Hoare法
  • 不同的方法,找出基准值,排的序列是不一样的
  • i记录基准值一开始在left位置的下标
  • r找到比基准值小的停下来,l找到比基准值大的停下来,互相交换
  • l和r相遇的时候,把i 记录基准值的初始下标和相遇位置交换

以左边为基准,先找右边再找左边,相遇的位置就是以右边为基准的值,要比基准小,才能交换

java 复制代码
    /**
     * Hoare法 划分排序找基准值
     * @param array
     * @param left
     * @param right
     * @return
     */
    private static int partition2(int[] array, int left, int right) {
        int tmp = array[left];
        int i  = left;//记录基准值一开始在left位置的下标
        while (left < right) {
            while (left < right && array[right] >= tmp) {
                right--;
            }
            while (left < right && array[left] <= tmp) {
                left++;
            }
            swap(array,left,right);
        }
        swap(array,i,left);
        return left;
    }

点击移步博客主页,欢迎光临~

相关推荐
李慕婉学姐4 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆5 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin6 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20056 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉6 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国6 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882486 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈7 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_997 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹7 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理