Java与算法之(2) - 快速排序
快速排序的基本思路是,每次选定数列中的一个基准数,将小于基准数的数字都放到基准数左边,大于基准数的数字都放到基准数右边。然后再分别对基准数左右的两个数列分别重复以上过程。仍以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<Integer> 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;
- }
Java与算法之(2) - 快速排序的更多相关文章
- java排序算法(五):快速排序
java排序算法(五):快速排序 快速排序是一个速度非常快的交换排序算法,它的基本思路很简单,从待排的数据序列中任取一个数据(如第一个数据)作为分界值,所有比它小的元素放到左边.所有比它大的元素放到右 ...
- Java排序算法之快速排序
Java排序算法之快速排序 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分 ...
- java排序算法之冒泡排序和快速排序
总结一下Java排序算法,以便记忆. 各类排序的时间复杂度: 排序方法 时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性 复杂性 直接插入排序 O(n2)O(n2) O( ...
- 算法相关——Java排序算法之快速排序(三)
0. 前言 本系列文章将介绍一些常用的排序算法.排序是一个非常常见的应用场景,也是开发岗位面试必问的一道面试题,有人说,如果一个企业招聘开发人员的题目中没有排序算法题,那说明这个企业不是一个" ...
- 常用Java排序算法
常用Java排序算法 冒泡排序 .选择排序.快速排序 package com.javaee.corejava; public class DataSort { public DataSort() { ...
- (转)java 排序算法
排序算法汇总(java实现,附源代码) 整理系统的时候发现了原来写的各种算法的总结,看了一下,大吃一惊,那时候的我还如此用心,具体的算法,有的已经模糊甚至忘记了,看的时候就把内容整理出来,顺便在熟 ...
- Java TimSort算法 源码 笔记
本来准备看Java容器源码的.但是看到一开始发现Arrays这个类我不是很熟,就顺便把Arrays这个类给看了.Arrays类没有什么架构与难点,但Arrays涉及到的两个排序算法似乎很有意思.那顺便 ...
- java排序算法(一):概述
java排序算法(一)概述 排序是程序开发中一种非常常见的操作,对一组任意的数据元素(活记录)经过排序操作后,就可以把它们变成一组按关键字排序的一组有序序列 对一个排序的算法来说,一般从下面三个方面来 ...
- java排序算法(四):冒泡排序
java排序算法(四):冒泡排序 冒泡排序是计算机的一种排序方法,它的时间复杂度是o(n^2),虽然不及堆排序.快速排序o(nlogn,底数为2).但是有两个优点 1.编程复杂度很低.很容易写出代码 ...
随机推荐
- Idea在导入有maven项目时,不能自动识别pom.xml
当在idea中导入maven项目时,不能自动识别pom文件,显示为普通橙色xml文件. 解决方法:点击最右侧侧边栏,点击添加(蓝的的小加号),选择你导入项目的pom.xml文件
- java.lang.NoSuchMethodError: com.itextpdf.text.pdf.PdfDiv.setKeepTogether(Z)V
用com.itextpdf.text.Document打印pdf报错 时间:2017-06-22 12:23:39,594 - 级别:[ERROR] - 消息: [other] Servlet.ser ...
- 【java】实现一个简单的正则:判断一个字符串是否全由数字组成
package 正则; public class TestIsNum { public static void main(String[] args) { String s1="abc&qu ...
- Java.util.Map排序输出
在java的众多Map实现中,Map基本上是不能保证顺序的(LinkedHashMap可以保证插入顺序或者访问顺序,TreeMap默认按照key升序但可以自定义Comparator),在开发过程中当数 ...
- 【NOIP模拟】cut
Description F大爷热爱切树.今天他找到一棵黑白树,不到两秒钟,F大爷就把这棵树切掉了.已知原先树上共n个点,每个点都是黑点或者白点,F大爷切去若干条边后,分成的若干个连通子树中每块恰有一个 ...
- 【NOIP模拟】从我背后出现
Description 给定n个点m条边的无向连通图,对于每条边求出强制选这条边后的最⼩⽣成树⼤⼩. \(n\leq 10^5,m\leq 2*10^5\) Input Format 第 1 行包含两 ...
- Linux 学习记录 二 (文件的打包压缩).
前言:本文参考<鸟哥的Linux 私房菜>,如有说的不对的地方,还请指正!谢谢! 环境:Centos 6.4 和window不同,在Linux压缩文件需要注意的是,压缩后的文件会 ...
- lumen安装后输出hello world
1.安装composer,具体请百度 2.composer 切换中国镜像,好处自己体会,命令如下 composer config -g repo.packagist composer https:// ...
- Python-String字符串的相关方法
- 防盗链与token运用
为什么要防盗链? 例如手机/PC应用,如果有人知道你的api地址,和应用格式,那么他人就可以利用这个接口进行盗链:盗取/盗用里面的数据. 防盗链特性: 1.因为是非开放性的,所以所有的接口都是封闭的, ...