快速排序 通透百万数据秒级排序

简介: 快速排序 通透百万数据秒级排序

快速排序

快速排序 是随机选中其中一个元素,进行元素筛选 一遍一遍将小于这个元素的放在左边,把大于元素的放在右边

之后两边再分别随机选择出来一个而元素继续上述操作

  • 选出对比元素,可以固定可以随机 可能会影响效率
  • 小的放在左边,大的放在右边
  • 持续递归
  • 拼接返回

动态图

理解实例

简易方便理解版本的快排

利用集合来演示快排

这个效率不会很好,但是很适合我们来理解快速排序的思路

public static ArrayList<Integer> quickSort(ArrayList<Integer> arr) {
        if (arr == null || arr.size() <= 1) {
            return arr;
        }
        int leader = arr.get(0);
        //存放左右的结果
        ArrayList<Integer> left = new ArrayList<>();
        ArrayList<Integer> right = new ArrayList<>();
        for (int i = 1; i < arr.size(); i++) {
            //根据左右条件添加
            if (arr.get(i) <= leader) {
                left.add(arr.get(i));
            } else {
                right.add(arr.get(i));
            }
        }
        //递归
        ArrayList<Integer> leftResult = quickSort(left);
        ArrayList<Integer> rightResult = quickSort(right);
        //    合并
        ArrayList<Integer> result = new ArrayList<>();
        result.addAll(leftResult);
        result.add(leader);
        result.addAll(rightResult);
        return result;
    }

标准版本

标准版的思路和简易版本有一定区别

这里是有两个指针一个指向前面 一个指向后面。根据选出的值来从右往左找小于这个数的值移动,之后从左边找大于值的数移动到右边,每一次交换两个数分别放在左右两边,直到左右指针相遇 就将这个数值放在相遇点,直到有序为止。

图解

重复这个过程一直到有序为止,

我们只需要编写一个定位方法,第一次就按照上图来讲low位置的左右两边交换好

之后只需要出去中位,左右递归就可以排序好数列了,至此百万数字秒级排序的快速排序思路完成

代码实现

package com.hyc.algorithm.sort;
import java.util.ArrayList;
/**
 * @projectName: DataStructure
 * @package: com.hyc.algorithm.sort
 * @className: QuickSort
 * @author: 冷环渊 doomwatcher
 * @description: TODO
 * @date: 2022/4/3 23:30
 * @version: 1.0
 */
public class QuickSort {
    public static void main(String[] args) {
        //ArrayList<Integer> arr = new ArrayList<>();
        //arr.add(3);
        //arr.add(1);
        //arr.add(9);
        //arr.add(2);
        //arr.add(6);
        //arr.add(8);
        //arr.add(7);
        //arr.add(5);
        //System.out.println(quickSort(arr));
        //int[] arr = {3, 1, 9, 2, 6, 8, 7, 5};
        int[] test = new int[8000000];
        //测试数据
        for (int i = 0; i < 8000000; i++) {
            test[i] = (int) (Math.random() * 800000);
        }
        long time = System.currentTimeMillis();
        quickSort(test);
        long end = System.currentTimeMillis();
        long t = ((end - time) / 1000);
        System.out.println("一共用时 " + t + "秒");
    }
    //简易版本
    public static ArrayList<Integer> quickSort(ArrayList<Integer> arr) {
        if (arr == null || arr.size() <= 1) {
            return arr;
        }
        int leader = arr.get(0);
        //存放左右的结果
        ArrayList<Integer> left = new ArrayList<>();
        ArrayList<Integer> right = new ArrayList<>();
        for (int i = 1; i < arr.size(); i++) {
            if (arr.get(i) <= leader) {
                left.add(arr.get(i));
            } else {
                right.add(arr.get(i));
            }
        }
        //递归
        ArrayList<Integer> leftResult = quickSort(left);
        ArrayList<Integer> rightResult = quickSort(right);
        //    合并
        ArrayList<Integer> result = new ArrayList<>();
        result.addAll(leftResult);
        result.add(leader);
        result.addAll(rightResult);
        return result;
    }
    //标准版快速排序
    public static void quickSort(int[] arr) {
        quickSort(arr, 0, arr.length - 1);
    }
    public static void quickSort(int[] arr, int low, int high) {
        if (low >= high) {
            return;
        }
        //已经交换过一次 中间值的为止不会变化了
        int partPoint = partition(arr, low, high);
        //递归左边
        quickSort(arr, low, partPoint - 1);
        //递归右边
        quickSort(arr, partPoint + 1, high);
    }
    //进行一次左右换位
    public static int partition(int[] arr, int low, int high) {
        int leader = arr[low];
        while (low < high) {
            while (low < high && arr[high] >= leader) {
                //从右边寻找第一个小于leader的数字
                high--;
            }
            //    交换值
            arr[low] = arr[high];
            while (low < high && arr[low] <= leader) {
                //从左边找到第一个大于leader的数字
                low++;
            }
            arr[high] = arr[low];
        }
        arr[low] = leader;
        return low;
    }
}

效率版

思路和标准版一致

//速度优化之后的快速排序
public static void optimizeQuickSort(int[] arr, int low, int high) {
    int l = low;
    int r = high;
    int pivot = arr[l + r / 2];
    int temp = 0;
    while (l < r) {
        while (arr[l] < pivot) {
            l += 1;
        }
        while (arr[r] > pivot) {
            r -= 1;
        }
        if (l >= r) {
            break;
        }
        temp = arr[l];
        arr[l] = arr[r];
        arr[r] = temp;
        if (arr[l] == pivot) {
            r -= 1;
        }
        if (arr[r] == pivot) {
            l += 1;
        }
    }
    //防止栈溢出
    if (l == r) {
        l += 1;
        r -= 1;
    }
    //防止栈溢出,当low指针0 r = 0 的时候就不许要排序递归左边了,
    if (low < r) {
        quickSort(arr, low, r);
    }
    //当 高位大于 左边指针的时候 就需要向右边递归了
    if (high > l) {
        quickSort(arr, l, high);
    }
}
目录
相关文章
|
算法 索引
|
存储 测试技术 C++
实践:几十亿条数据分布在几十个节点上的毫秒级实时排序方法
#引子 先简单的问一下, 你如何解决这样的需求: ``` 对一堆数据按某字段排序,获取第100-10条的数据。 ``` 假设你面对的数据是个单节点,简单来说,就是一个mysql数据库, 很自然地用 select a from tb order by a limit 100, 10; ![imag
4219 0
|
13天前
|
存储 缓存 NoSQL
京东面试:亿级黑名单 如何设计?亿级查重 呢?(答案含:布隆过滤器、布谷鸟过滤器)
尼恩,40岁的老架构师,近期在读者交流群中分享了几个大厂面试题及其解决方案。这些问题包括亿级数据查重、黑名单存储、电话号码判断、安全网址判断等。尼恩给出了三种解决方案:使用BitMap位图、BloomFilter布隆过滤器和CuckooFilter布谷鸟过滤器。这些方法不仅高效,还能显著提升面试表现。尼恩还建议大家系统化学习,刷题《尼恩Java面试宝典PDF》,并提供简历修改和面试辅导,帮助大家实现“offer自由”。更多技术资料和PDF可在公众号【技术自由圈】获取。
|
11月前
|
算法 搜索推荐 Java
算法分析 | 第二套(最差、平均和最佳情况)
算法分析 | 第二套(最差、平均和最佳情况)
42 0
|
算法
【浅谈算法】二分查找(保姆级)
【浅谈算法】二分查找(保姆级)
38 0
|
存储 缓存 自然语言处理
阿里二面:MySQL索引是怎么支撑千万级表的快速查找?
在 MySQL 官方提到,改善操作性能的最佳方法 SELECT 在查询中测试的一个或多个列上创建索引。索引条目的作用类似于指向表行的指针,从而使查询可以快速确定哪些行与WHERE子句中的条件匹配,并检索这些行的其他列值。所有MySQL数据类型都可以建立索引。
272 0
【八大排序(四)】快排-到底多快才能追上奔驰车里的夏树?(下)
【八大排序(四)】快排-到底多快才能追上奔驰车里的夏树?(下)
【八大排序(四)】快排-到底多快才能追上奔驰车里的夏树?(下)
|
SQL 关系型数据库 MySQL
线上千万级大表排序:优化攻略揭秘,轻松应对海量数据!
前段时间应急群有客服反馈,会员管理功能无法按到店时间、到店次数、消费金额 进行排序。经过排查发现是Sql执行效率低,并且索引效率低下。遇到这样的情况我们该如何处理呢?今天我们聊一聊Mysql大表查询优化。
线上千万级大表排序:优化攻略揭秘,轻松应对海量数据!
|
存储 搜索推荐 算法
“插入排序:小数据量排序的王者“
“插入排序:小数据量排序的王者“
129 0