【Java】快速排序

快速排序使用的是典型的分支思想,对于一个典型子数组A[p..r],进行快速排序的过程也是典型的三步分治过程,即分解、解决和合并。

分解:划分A[p..r]为A[p..q-1]以及A[q+1..r]两个子数组,而且q满足前一个子数组均不大于A[q],后一个子数组均不小于A[q]

解决:对两个子数组分别进行递归或者迭代的方式进行排序解决。

合并:子数组都是原址排序,不需要合并就已经有序。

 

递归方法:递归调用排序函数进行子数组的排序

QS(p,q-1); 

QS(q+1,r);

迭代方法:使用堆栈实现迭代机制,通过堆栈的先进后出来代替递归方法,通过迭代变量的控制以及循环条件的判断来控制堆栈的出入和迭代的次数,实现对迭代过程的控制。

递归实现

package QuickSort;

public class QSRecursive {

	public QSRecursive() {
		super();
	}

	public void QUICKSORT(int p, int r, int[] A) {
		if (p < r) {
			int q = PARTITION(p, r, A);
			QUICKSORT(p, q - 1, A);
			QUICKSORT(q + 1, r, A);
		}
	}

	public int PARTITION(int p, int r, int[] A) {
		int x = A[r];
		int i = p - 1;
		for (int j = p; j < r; j++) {
			if (A[j] <= x) {
				i++;
				int tmp = A[i];
				A[i] = A[j];
				A[j] = tmp;
			}
		}
		int tmp = A[i + 1];
		A[i + 1] = A[r];
		A[r] = tmp;
		return i + 1;
	}

迭代实现

package QuickSort;

import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;

public class QSIterative {
	public QSIterative() {
		super();
	}

	public void QUICKSORT(int p, int r, int[] A) {
		LinkedList<Integer> linkedList = new LinkedList<Integer>();
		if (p < r) {
			linkedList.push(r);
			linkedList.push(p);
			while (!linkedList.isEmpty()) {
				int l = linkedList.pop();
				int s = linkedList.pop();
				int q = PARTITION(l, s, A);
				if (l < q - 1) {
					linkedList.push(q - 1);
					linkedList.push(l);
				}
				if (s > q + 1) {
					linkedList.push(s);
					linkedList.push(q + 1);
				}
			}
		}
	}

	public int PARTITION(int p, int r, int[] A) {
		int x = A[r];
		int i = p - 1;
		for (int j = p; j < r; j++) {
			if (A[j] <= x) {
				i++;
				int tmp = A[i];
				A[i] = A[j];
				A[j] = tmp;
			}
		}
		int tmp = A[i + 1];
		A[i + 1] = A[r];
		A[r] = tmp;
		return i + 1;
	}

	static void showArray(int n, int[] A) {
		for (int i = 0; i < n; i++) {
			System.out.printf("%5s", A[i] + " ");
			if ((i + 1) % 10 == 0)
				System.out.print("\n");
		}
	}

	void randomArray(int n, int[] A) {
		//种子数设置
		Random random = new Random(n);
		//随机生成
		for (int i = 0; i < n; i++) {
			A[i] = Math.abs(random.nextInt()) % n;
		}
		System.out.println("随机生成数据如下:");
		showArray(n, A);
	}

	public static void main(String[] args) {
		int[] A;
		int[] B;
		long startTime, endTime;
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入随机数据规模:");
		int n = scanner.nextInt();
		A = new int[n];
		B = new int[n];
		// 数据输入
		/*
		 * for (int i = 0; i < n; i++) { A[i] = scanner.nextInt(); }
		 */
		scanner.close();

		QSIterative qsIterative = new QSIterative();
		// 随机生成测试数据
		qsIterative.randomArray(n, A);
		// 拷贝数据到数组B
		System.arraycopy(A, 0, B, 0, n);
		// 迭代快排
		startTime = System.nanoTime(); // 获取开始时间
		qsIterative.QUICKSORT(0, n - 1, A);
		endTime = System.nanoTime(); // 获取结束时间
		// 打印时间以及迭代结果
		System.out.println("\n迭代快排花费时间:" + (endTime - startTime) + "ns," + "结果如下:");
		showArray(n, A);
		// 递归快排
		QSRecursive qsRecursive = new QSRecursive();
		startTime = System.nanoTime(); // 获取开始时间
		qsRecursive.QUICKSORT(0, n - 1, B);
		endTime = System.nanoTime(); // 获取结束时间
		System.out.println("\n递归快排花费时间:" + (endTime - startTime) + "ns," + "结果如下:");
		showArray(n, B);
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值