数据结构与算法 - 快速排序Java代码实现

前面几篇博文用代码+注释的方式介绍了几种基本的排序, 文末有链接, 可以熟悉一下.
今天的还是介绍一种适合大数据量的排序算法, 即快速排序, 简称快排, 也是面试中常见的算法题, 我试着用注释给详细阐述了实现逻辑

一句话介绍实现逻辑: 使用分治思想, 找一个基准点(随意选, 本代码选的最末尾一个元素), 用来给数组内的元素分界, 通过挪动元素, 使得左边比基准点小, 右边的元素比基准点大, 然后, 使用相同的逻辑, 递归左右两边的元素, 直到子集中只剩下一个元素,得到最终排序好的结果.

说起来容易, 实现起来, 还需要一番推敲, 好好研究一下代码, 欢迎读者朋友给予指正, 一起交流学习.
代码中有详细注释, 如下:

import org.junit.Test;

/**
 * 功能说明:快速排序
 * 开发人员:@author MaLi
 */
public class T05_QuickSort {
    
    
    /**
     * 排序入口
     *
     * @param arr 待排序数组
     */
    public void sort(int[] arr) {
    
    
        if (arr == null || arr.length <= 1) {
    
    
            return;
        }
        sort(arr, 0, arr.length - 1);
    }

    /**
     * 排序逻辑: 一句话概括, 找一个基准点(该程序选end位置的元素作为基准点), 基准点左边的比都是小的, 右边都是比基准点大的
     * 然后分治, 基准点两边各自执行相同的逻辑: 再各自找基准点, 各自的基准点的两边一边小, 一边大, 然后继续分治...
     * 直到基准点的两边只有一个元素
     * 思想是分治, 逻辑如上, 编程实现如下:
     * 1, 使用递归
     * 2, 选end, 也就是数组的最后一个元素作为基准点
     * 3, 选i作为 "已排序区间" 与"未排序区间"的分界
     * 4, 遍历未排序区间(使用j作为指针的循环), 如果比基准点小, 就放到已排序区间, 编程代码就是: 与i所在位置交换, i挪动到下一个位置(这是第一步)
     * 5, 关于j指针的循环遍历完成后, 交换基准点和i --> 目的: 为下面分治做准备, 这样基准点的两边有各自的特点: 左边都比基准点小, 右边反之;
     * 6, 基准点的两边递归上面的逻辑, 直到基准点的两边剩余一个元素, 递归结束, 数组已经有序了.
     *总结: 每一遍循环, 实现的结果有两个: 1,小的和大的分界;2, 基准点放到分界位置 --> 开启新的分治阶段
     *
     * @param arr   待排序数组
     * @param start 首元素位置
     * @param end   尾元素位置
     */
    public void sort(int[] arr, int start, int end) {
    
    
        // 递归结束条件: 只有一个元素
        if (start >= end) {
    
    
            return;
        }
        // 设定i为已排序与未排序的分界, 首先i指向未排序区间的第一个位置(这里刚开始, 初始化指向start)
        int i = start;
        // 关键逻辑1: 将数组中除去基准点外, 所有的元素以比基准点为标准分大小, 小的放左边, 大的放右边
        // 放左与放右, 体现在代码上就是是否交换i与j位置的元素, 如果小于基准点, 那么就将这个元素放到边界内
        for (int j = start; j < end; j++) {
    
    
            if (arr[j] < arr[end]) {
    
    
                // 交换一下就放到边界内了
                swap(arr, i, j);
                // 还要把i边界往后挪动以为
                i++;
            }
        }
        // 把基准点放到边界位置上, 这样才做到左边的比基准点小, 右边的比基准点大
        swap(arr, i, end);
        //递归: 分治即把左右两边按照相同逻辑处理
        sort(arr, start, i - 1);
        sort(arr, i + 1, end);
    }

    /**
     * 交换数组中两个位置上的元素
     *
     * @param arr    待排序数组
     * @param index1 交换位置的角标1
     * @param index2 交换位置的角标2
     */
    public void swap(int[] arr, int index1, int index2) {
    
    
        int tmp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = tmp;
    }
    
    // 以下为测试代码
    @Test
    public void testSort() {
    
    
        int[] arr = {
    
    9, 8, 7, 6, 5, 4, 3, 2, 1};
        sort(arr);
        for (int i : arr) {
    
    
            System.out.println(i);
        }
        System.out.println("-------------------");
        arr = new int[]{
    
    1};
        sort(arr);
        for (int i : arr) {
    
    
            System.out.println(i);
        }
        System.out.println("-------------------");
        arr = new int[]{
    
    };
        sort(arr);
        System.out.println(arr);
    }
}

排序算法快捷进入

1, 插入排序
2, 选择排序
3, 归并排序
4, 快速排序
5, 冒泡排序
不断补充…

猜你喜欢

转载自blog.csdn.net/malipku/article/details/121366493