十大排序算法之二 - 快速排序

十大排序算法之二 - 快速排序

1.快速排序的介绍

  • 同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的
  • 不同的是,冒泡排序在每一轮中只把1个元素冒泡到数列的一端,而快速排序则在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成两个部分,这种思路就叫作分治法
  • 基准元素的选择
    • 基准元素,英文是pivot,在分治过程中,以基准元素为中心,把其他元素移动到它的左右两边,我们可以随机选择一个元素作为基准元素,并且让基准元素和数列首元素交换位置

2. 双边排序法(双指针)

2.1 实现图解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 Java代码实现

package com.lagou.quickSort;

/**
 * @author 云梦归遥
 * @date 2022/5/16 18:45
 * @description 快速排序法 - 双边排序法
 */
public class QuickSortByDoubleMethod {
    public int[] quickSort(int[] array){
        if (array == null) return null;
        // 双边循环法
        doubleSideSort(array, 0, array.length - 1);
        return array;
    }

    // 双边循环法
    private void doubleSideSort(int[] array, int leftIndex, int rightIndex){
        if (array == null || rightIndex <= leftIndex) return;
        int flag = leftIndex;
        int newLeftIndex = leftIndex;
        int newRightIndex = rightIndex;
        while (true){
            // 右指针判断
            while (leftIndex < rightIndex && array[rightIndex] >= array[flag]){
                rightIndex--;
            }
            // 左指针判断
            while (leftIndex < rightIndex && array[leftIndex] <= array[flag]){
                leftIndex++;
            }
            // 交换左右指针的数据
            if (leftIndex < rightIndex){
                int temp = array[rightIndex];
                array[rightIndex] = array[leftIndex];
                array[leftIndex] = temp;
            }
            // 左右指针相遇,与 flag 交换数据
            if (leftIndex == rightIndex){
                // 交换值
                int temp = array[leftIndex];
                array[leftIndex] = array[flag];
                array[flag] = temp;
                flag = leftIndex;
                break;
            }
        }
        // 递归判断
        // 对 flag 左边的数组进行 双边循环
        doubleSideSort(array, newLeftIndex, flag - 1);
        // 对 flag 右边的数组进行 双边循环
        doubleSideSort(array, flag + 1, newRightIndex);
    }
}

进行测试

package com.lagou.quickSort.test;

import com.lagou.quickSort.QuickSortByDoubleMethod;

import java.util.Arrays;

/**
 * @author 云梦归遥
 * @date 2022/5/16 19:11
 * @description
 */
public class QuickSortByDoubleTest {
    public static void main(String[] args) {
        QuickSortByDoubleMethod quickSortMethod = new QuickSortByDoubleMethod();
        int[] array = {3, 5, 2, 4, 6, 1, 7, 9, 8};
        int[] sort = quickSortMethod.quickSort(array);
        System.out.println("【快速排序 - 双边循环】" + Arrays.toString(sort));
    }
}

在这里插入图片描述

3.单边循环法(单指针)

3.1 实现图解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 Java实现

package com.lagou.quickSort;

/**
 * @author 云梦归遥
 * @date 2022/5/16 20:39
 * @description 快速排序法 - 单边排序法
 */
public class QuickSortBySingleMethod {
    public int[] quickSort(int[] array){
        if (array == null) return null;

        // 调用单边排序法来进行处理
        singleSort(array, 0, array.length - 1);
        return array;
    }

    private void singleSort(int[] array, int leftIndex, int rightIndex){
        if (array == null || leftIndex >= rightIndex) return;
        int flag = leftIndex;
        int move = flag; // 记录小于 flag 范围的数
        int newLeftIndex = leftIndex;
        int newRightIndex = rightIndex;

        // 循环判断
        int temp = 0;
        for (int i = leftIndex; i <= rightIndex; i++){
            if (array[flag] > array[i]){
                move++;
                temp = array[i];
                array[i] = array[move];
                array[move] = temp;
            }
        }
        // 交换 flag 与 move
        temp = array[move];
        array[move] = array[flag];
        array[flag] = temp;

        // 进行迭代,处理 move 两边的数组
        singleSort(array, newLeftIndex, move - 1);
        singleSort(array, move + 1, newRightIndex);
    }
}

进行测试

package com.lagou.quickSort.test;

import com.lagou.quickSort.QuickSortBySingleMethod;

import java.util.Arrays;

/**
 * @author 云梦归遥
 * @date 2022/5/16 20:53
 * @description
 */
public class QuickSortBySingleTest {
    public static void main(String[] args) {
        QuickSortBySingleMethod quickSortBySingleMethod = new QuickSortBySingleMethod();
        int[] array = {3, 5, 2, 4, 6, 1, 7, 9, 8};
        int[] sort = quickSortBySingleMethod.quickSort(array);
        System.out.println("【快速排序 - 单边循环】" + Arrays.toString(sort));
    }
}

在这里插入图片描述

4.总结

  • 快速排序时间复杂度为:O(nlogn)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值