Java与算法之(2) - 快速排序

原创 2016年08月30日 15:11:52

快速排序的基本思路是,每次选定数列中的一个基准数,将小于基准数的数字都放到基准数左边,大于基准数的数字都放到基准数右边。然后再分别对基准数左右的两个数列分别重复以上过程。仍以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 快速排序算法

  • 2015年07月21日 17:04
  • 2KB
  • 下载

快速排序算法JAVA实现

  • 2010年12月13日 16:57
  • 27KB
  • 下载

算法入门--快速排序2(随机产生分割主元素)

#include #include /* 随机快速排序算法,每次随机产生一个p...r之间的数作为主元交换对象,用于分割数组。 */ void exchange(int *a,int i,int...

第十六周项目1(2)--验证算法之快速排序

问题及代码: /* * Copyright (c)2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名称:项目1.cpp * 作 ...

快速排序(2)算法改进--小的子文件、三者取中、重复关键字三路划分

标签(空格分隔): 排序算法 1. 小的子文件由于快速排序会递归的调用自身的许多小文件,因而要对小的子文件尽可能使用高效的算法 三者取其中快速排序 重复关键字-三路划分快速排序...

算法复习(2) 快速排序

关于快速排序,一般都认为是通常情况下性能最好的,也确实是。因此对其的讨论都是在于如何能够使它更快。因此看一下快排的一般版本和随机版本。//一般版本 int Partition(int* arr, in...

基础算法(2):快速排序(随机划分+三数取中划分+ 随机三数取中划分+尾递归)

快速排序:                  简介:快速排序是一种排序算法,包含n个数的输入数组,最坏情况为O(n^2),但是平均性能非常好:期望运行时间为O(n*lg(n))。           ...

算法精解----快速排序2

前面排序方法有个很明显的bug就是递归次数很多,而且递归进去的时候什么也不干。这样非常浪费CPU资源,所以呢,现在说说另外一种快速排序的方法,这种方法和前面的不同,前面的方法是K值分别和大于它的值和小...

《算法导论》学习笔记(2)——快速排序

快速排序,是一种基于分治思想的排序算法。分治,简单来说就是“大事化小”,从而达到最基本的问题,然后再将其合一。          在快速排序算法中,每次需要把一个数组A[p...r]分为三部分: A[...

算法导论学习笔记(2)---快速排序

快速排序 快速排序平均复杂度是nlogn,记录一下快速排序的思路: 1.分治的思想,把数组分成两份,两份分成4分,这样分到足够小,就能很好排序咯,然后把他们合起来,排序完成。 2.该分治思想和合...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java与算法之(2) - 快速排序
举报原因:
原因补充:

(最多只允许输入30个字)