博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java与算法之(2) - 快速排序
阅读量:4326 次
发布时间:2019-06-06

本文共 2842 字,大约阅读时间需要 9 分钟。

快速排序的基本思路是,每次选定数列中的一个基准数,将小于基准数的数字都放到基准数左边,大于基准数的数字都放到基准数右边。然后再分别对基准数左右的两个数列分别重复以上过程。仍以4 3 6 2 7 1 5为例。

选定最左侧数字4为基准数,首先从右开始向左找小于4的数,找到第一个数1后停止。然后从左开始向右找到第一个大于4的数,即6。

交换这两个数的位置,得到

继续寻找,仍然从右边开始,从上一步找到1的位置向左寻找小于4的数,找到2停止。然后从左边找到6的位置向右找大于4的数。右移一格后,和右侧来的“探路者”相遇了,这意味着这一轮排序结束。
最后把结束位置的数和基准数交换

观察完成后的数列,可以看到以基准数4为分界线,左边的数全都比4小,右边的数全都比4大。接下来分别对左边的2 3 1和右边的7 6 5重复上面的排序步骤。

2 3 1
以2为基准数 -> 2 1 3 -> 1 2 3
7 6 5
以7为基准数 -> 5 6 7
我们例子中的数字较少,如果数列足够长,对第一次排序后得到的子数列排序,将再得到两个子数列,然后再一分为二、二分为四。。。直到以基准数拆分后两边都只剩下一个数字。首先来看递归形式的实现代码

public class QuickSort {    public void sort(int left, int right, int... numbers) {        if (left >= right) {            return;        }        int temp = numbers[left];        int t = 0;        int i = left;        int j = right;        while (i != j) {            // 先从右往左找            while (numbers[j] >= temp && i < j)                j--;            // 再从左往右找            while (numbers[i] <= temp && i < j)                i++;            // 交换两个数在数组中的位置            if (i < j) {                t = numbers[i];                numbers[i] = numbers[j];                numbers[j] = t;            }        }        // 将基准数归位        numbers[left] = numbers[i];        numbers[i] = temp;        sort(left, i - 1, numbers);        sort(i + 1, right, numbers);    }}

测试代码

public static void main(String[] args) {        int[] numbers = new int[] { 4, 3, 6, 2, 7, 1, 5 };        new QuickSort().sort(0, numbers.length - 1, numbers);        System.out.print("after: ");        for (int i = 0; i < numbers.length; i++) {            System.out.print(numbers[i] + "  ");        }        System.out.println();    }

输出

after: 1  2  3  4  5  6  7

另一种实现方式是使用栈代替递归

public void sortWithoutRecursion(int left, int right, int... numbers) {        LinkedList
stack = new LinkedList<>(); int index; stack.push(left); stack.push(right); while (!stack.isEmpty()) { right = stack.pop(); left = stack.pop(); index = partition(left, right, numbers); if (left < index - 1) { stack.push(left); stack.push(index - 1); } if (right > index + 1) { stack.push(index + 1); stack.push(right); } } } public int partition(int left, int right, int... numbers) { int temp = numbers[left]; while (left < right) { while (numbers[right] >= temp && left < right) right--; numbers[left] = numbers[right]; while (numbers[left] <= temp && left < right) left++; numbers[right] = numbers[left]; } numbers[left] = temp; return left; }

---------------------

原文:https://blog.csdn.net/autfish/article/details/52368963

转载于:https://www.cnblogs.com/xiaoshen666/p/11059535.html

你可能感兴趣的文章
C++标准库分析总结(三)——<迭代器设计原则>
查看>>
Ibatis 配置问题
查看>>
Notability 3.1 for Mac 中文共享版 – 好用的文本笔记工具
查看>>
HDU 2089 数位dp入门
查看>>
How do I resolve the CodeSign error: CSSMERR_TP_NOT_TRUSTED?
查看>>
linux下添加定时任务
查看>>
python的第三篇--安装Ubuntu、pycharm
查看>>
LeetCode 1092. Shortest Common Supersequence
查看>>
《区块链技术与应用》北京大学肖臻老师公开课 笔记
查看>>
139句
查看>>
购买《哈利波特》书籍
查看>>
谈谈一些网页游戏失败的原因到底有哪些?(转)
查看>>
备案的问题
查看>>
asp.net下ajax.ajaxMethod使用方法
查看>>
win10+mongodb安装配置
查看>>
window7修改hosts文件
查看>>
【Leetcode_easy】720. Longest Word in Dictionary
查看>>
地铁时光机第一阶段冲刺一
查看>>
Code Smell那么多,应该先改哪一个?
查看>>
站立会议02(一期)
查看>>