排序算法之快速排序

排序算法之快速排序

前2段是废话可直接看第3段,coding多年一些常见算法及原理还是记得的,平时习惯了IDE去 “.” 出一些方法,在跳槽面试中让编写算法及优化时也是抓瞎,其实算法原理应该是上动态图片更直观些的,无奈曾经遇到过大神制作的动图没有保存,自己又比较笨拙不会制作,但文章结尾会贴出本人参照较好的文章供大家一起分析。

在此也声明下,本人学习期间会参照一些老师及大神的书籍或博客,个人认为我不懂就要和懂的人学习知识并吸收总结成自己的,这其实没有什么丢人的,所以博客、代码均通过收集资料分析、编写、优化、测试及总结整理后书写博客与大家分享,目的在于自我加深印象,分享及传播知识。希望大家就实际问题相互学习探讨,请勿互掐。

快速排序:采用 三数取中法+分治法+挖坑填数

三数取中法:为提升效率避免分组不合理的情况,比如逆序数组,提前将数组选左中右3个数将数组排序分割,之后再进行分治法排序,图解可参照参考博客[2] 的三数取中法 。

分治法:将数组从中分割开2部分,1变2,2变4,4变8…分割后在进行排序。

挖坑填数:本质是元素交换。先把基准值挖出来,位置留出来为坑1;从后向前找到比基准小的元素挖出来,此位置为坑2,将元素填到坑1中;从前往后找到比基准大的元素挖出来,此位置为坑3,放到刚才挖的坑2中;将基准值填补到坑3中,然后分治递归快排。总结就是挖了三个坑:坑1(基准坑)、坑2、坑3,有了三块土:土1(基准值)、土2、土3,土2填坑1,土3填坑2,土1(基准值)填坑3,图解可参照参考博客[1] 的快速排序。

直接上测试代码:

import java.util.Arrays;

/**
 * @Author: Wenx
 * @Description: 快速排序
 * @Date: Created in 2020/3/6 17:35
 * @Modified By:
 */
public class QuickSort<T extends Comparable<T>> implements Sort<T> {
    @Override
    public void sort(T[] values) {
        int size = values.length;
        int low = 0;
        int high = size - 1;
        sort(values, low, high);
    }

    private void sort(T[] values, int low, int high) {
        if (low < high) {
            dealPivot(values, low, high);
            int pivotIdx = partition(values, low, high);
            sort(values, low, pivotIdx - 1);
            sort(values, pivotIdx + 1, high);
        }
    }

    private void dealPivot(T[] values, int low, int high) {
        int mid = (low + high) / 2;
        if (values[low].compareTo(values[mid]) == 1) {
            swap(values, low, mid);
        }
        if (values[low].compareTo(values[high]) == 1) {
            swap(values, low, high);
        }
        if (values[high].compareTo(values[mid]) == -1) {
            swap(values, high, mid);
        }
        swap(values, high - 1, mid);
    }

    private int partition(T[] values, int low, int high) {
        int l = low;
        int r = high;
        // 挖坑1:保存基准的值
        T pivot = values[low];
        while (l < r) {
            // 挖坑2:从后向前找到比基准小的元素,插入到基准位置坑1中
            while (l < r && values[r].compareTo(pivot) > -1) {
                r--;
            }
            values[l] = values[r];
            // 挖坑3:从前往后找到比基准大的元素,放到刚才挖的坑2中
            while (l < r && values[l].compareTo(pivot) < 1) {
                l++;
            }
            values[r] = values[l];
        }
        // 基准值填补到坑3中,准备分治递归快排
        values[l] = pivot;
        return l;
    }

    private void swap(T[] values, int a, int b) {
        T t = values[a];
        values[a] = values[b];
        values[b] = t;
    }

    public static void main(String[] args) {
        Integer[] values = {1, 5, 4, 3, 2, 6, 7, 8, 9};
        Sort<Integer> sort = new QuickSort<>();
        long startTime = System.nanoTime();
        sort.sort(values);
        long endTime = System.nanoTime();
        System.out.printf("耗时:%d ns, %s\n", endTime - startTime, Arrays.toString(values));
    }
}

留个接口方便后续操作:

/**
 * @Author: Wenx
 * @Description: 排序接口
 * @Date: Created in 2020/3/5 17:15
 * @Modified By:
 */
public interface Sort<T extends Comparable<T>> {
    void sort(T[] values);
}

总结:重点在于理解原理,使之变为自己的知识,编码可参照众多实现形式,每个人理解及想法均有差异,结合他人及自己想法转化实践就好了~

参考博客:

[1] https://blog.csdn.net/dp_dp/article/details/80543290

[2] https://blog.csdn.net/jiangtianjiao/article/details/88929408

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值