快速排序算法:小学生也能看就懂!

3 篇文章 0 订阅
2 篇文章 0 订阅
本文深入解析了快速排序算法,一种基于分治策略的高效排序方法。文章详细介绍了快速排序的基本思想,即通过一趟排序将数据分割成独立的两部分,使一部分数据都比另一部分数据小,再递归地对这两部分数据进行排序。通过具体步骤和Java代码实现,展示了快速排序的工作原理和操作流程。
摘要由CSDN通过智能技术生成

1、简介

快速排序(Quicksort)是对冒泡排序的一种改进,快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

2、原理详细分析

  1. 从要排序的数组中选择一个参考值,一般为第一个或者最后一个,记为B,这里我们选最后一个作为参考值。
  2. 用一个指针L指向左边第一个,再用一个指针R指向右边起第二个(因为第一个已经作为参考值了)。
  3. 判断左边指针指向的值是否小于参考值,如果小于则向右移动,直到移动到L指针指向的值大于参考值则停下来;L指针停下来之后,R指针开始向右移动,直到R指针指向的值小于参考值B,则停下来;此时L和R指针都停了下来,也就意味着L>B,R<B,然后让L和R的值交换。交换之后继续移动。
  4. 当L指针和R指针相遇时,指针不需要再移动。1、如果共同指向的值大于参考值B,则将共同指向的值与B交换,本轮排序完成,那么本轮可确定位置的值就是L、R共同指向的值,然后以L、R共同指向的值为分界线,将左边和右边部分分成两组,分别重复以上四个步骤,即可完成排序; 2、如果共同指向的值小于参考值B,则本轮排序完成,可以确定位置的值是B,因为B在最右边,此时B右边已经没有数据了,只需要将B左边的数据重复以上四个步骤即可。

首轮排序
图1. 第一轮排序

在这里插入图片描述
图2. 递归排序

3、Java代码实现

public class QuickSort {

    /**
     * 快速排序
     *
     * @param array      待排序数组
     * @param marker     标记的参考值
     * @param leftIndex  左边指针所指向的索引
     * @param rightIndex 右边指针所指向的索引
     */
    private static void sort(int[] array, int marker, int leftIndex, int rightIndex) {
        if (array.length < 2) {
            return;
        }
        while (true) {
            //左右指针指到同一个数时,一轮排序结束
            if (leftIndex == rightIndex) {
                //如果这个数比标记数大则交换,此时这个数为已排好的数;否则标记为排好的数
                if (array[marker] < array[leftIndex]) {
                    change(array, marker, leftIndex);
                    //递归,进入下一轮排序,分别排右边和左边的
                    if (leftIndex < array.length - 3) {
                        //右边排序
                        sort(array, array.length - 1, leftIndex + 1, array.length - 2);
                    }
                    if (leftIndex > 1) {
                        //左边排序
                        sort(array, leftIndex - 1, 0, leftIndex - 2);
                    }
                } else {
                    //标记数已排好,如【3,2,5】,标记数为5,已排好,只需要排3,2即可。
                    if (leftIndex > 1) {
                        //左边排序
                        sort(array, leftIndex, 0, leftIndex - 1);
                    }
                }
                //退出循环
                break;
            }
            //如果左边指针数小于等于标记数则把指针右移(加等于是因为数组可能存在重复的数值)
            if (array[leftIndex] <= array[marker]) {
                leftIndex++;
                continue;
            }
            //如果右边指针数大于等于标记数则把指针左移(加等于是因为数组可能存在重复的数值)
            if (array[rightIndex] >= array[marker]) {
                rightIndex--;
                continue;
            }
            //当左边指针值大于标记数,右边指针小于标记数时,将左右指针值交换
            change(array, leftIndex, rightIndex);
        }
    }

    /**
     * 交换数值
     *
     * @param array  数组
     * @param index1 要交换的数索引
     * @param index2 要交换的数索引
     */
    static void change(int[] array, int index1, int index2) {
        int temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    public static void main(String[] args) {
        int[] array = {3, 5, 8, 1, 2, 9, 4, 7, 6};
        sort(array, array.length - 1, 0, array.length - 2);
        StringBuilder sb = new StringBuilder();
        for (int i : array) {
            sb.append(i);
            sb.append(",");
        }
        System.out.println(sb.toString());
    }
}

运行结果
在这里插入图片描述
试一下有重复数据:
在这里插入图片描述
运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值