三路快速排序 java_java中三路快速排序的实现

当我们要排序数组中存在大量的重复的数据。如果我们将分割后数组分成三部分,即arr[0,1,2~l]< v, arr[l+1,r]=v,arr[r+1...arr.length-1]>v.我们可以将等于v数组直接过滤调,这样当存在大量的重复数组的时候,性能能够大幅度提高。

下面是三路快速排序的Java代码的实现:

package com.newtouch.data.sort;

import com.newtouch.data.test.SortTestHelper;

public class QuickSortThreeWays {

// 我们的算法类不允许产生任何实例

private QuickSortThreeWays() {

}

private static void sort(Comparable[] arr, int l, int r) {

if (l >= r)

return;

// 随机在arr[l...r]的范围中, 选择一个数值作为标定点pivot

swap(arr, l, (int) (Math.random() * (r - l + 1)) + l);

Comparable v = arr[l];

int lt = l; // arr[l+1...lt] < v

int gt = r + 1; // arr[gt...r] > v

int i = l + 1; // arr[lt+1...i) == v

while (i < gt) {

if (arr[i].compareTo(v) < 0) {

swap(arr, i, lt + 1);

i++;

lt++;

} else if (arr[i].compareTo(v) > 0) {

swap(arr, i, gt - 1);

gt--;

} else { // arr[i] == v

i++;

}

}

swap(arr, l, lt);

sort(arr, l, lt - 1);

sort(arr, gt, r);

}

public static void sort(Comparable[] arr) {

int n = arr.length;

sort(arr, 0, n - 1);

}

private static void swap(Object[] arr, int i, int j) {

Object t = arr[i];

arr[i] = arr[j];

arr[j] = t;

}

// 测试 QuickSort3Ways

public static void main(String[] args) {

// 三路快速排序算法也是一个O(nlogn)复杂度的算法

// 可以在1秒之内轻松处理100万数量级的数据

int N = 1000000;

Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);

SortTestHelper.testSort("com.newtouch.data.sort.QuickSortThreeWays", arr);

return;

}

}

测试类SortTestHelper的实现:

package com.newtouch.data.test;

import java.lang.reflect.Method;

import java.lang.Class;

import java.util.Random;

public class SortTestHelper {

// SortTestHelper不允许产生任何实例

private SortTestHelper() {

}

// 生成有n个元素的随机数组,每个元素的随机范围为[rangeL, rangeR]

public static Integer[] generateRandomArray(int n, int rangeL, int rangeR) {

assert rangeL <= rangeR;

Integer[] arr = new Integer[n];

for (int i = 0; i < n; i++)

arr[i] = new Integer((int) (Math.random() * (rangeR - rangeL + 1) + rangeL));

return arr;

}

// 生成一个近乎有序的数组

// 首先生成一个含有[0...n-1]的完全有序数组, 之后随机交换swapTimes对数据

// swapTimes定义了数组的无序程度:

// swapTimes == 0 时, 数组完全有序

// swapTimes 越大, 数组越趋向于无序

public static Integer[] generateNearlyOrderedArray(int n, int swapTimes) {

Integer[] arr = new Integer[n];

for (int i = 0; i < n; i++)

arr[i] = new Integer(i);

for (int i = 0; i < swapTimes; i++) {

int a = (int) (Math.random() * n);

int b = (int) (Math.random() * n);

int t = arr[a];

arr[a] = arr[b];

arr[b] = t;

}

return arr;

}

// 打印arr数组的所有内容

public static void printArray(Object[] arr) {

for (int i = 0; i < arr.length; i++) {

System.out.print(arr[i]);

System.out.print(' ');

}

System.out.println();

return;

}

// 判断arr数组是否有序

public static boolean isSorted(Comparable[] arr) {

for (int i = 0; i < arr.length - 1; i++)

if (arr[i].compareTo(arr[i + 1]) > 0)

return false;

return true;

}

// 测试sortClassName所对应的排序算法排序arr数组所得到结果的正确性和算法运行时间

public static void testSort(String sortClassName, Comparable[] arr) {

// 通过Java的反射机制,通过排序的类名,运行排序函数

try {

// 通过sortClassName获得排序函数的Class对象

Class sortClass = Class.forName(sortClassName);

// 通过排序函数的Class对象获得排序方法

Method sortMethod = sortClass.getMethod("sort", new Class[]{Comparable[].class});

// 排序参数只有一个,是可比较数组arr

Object[] params = new Object[]{arr};

long startTime = System.currentTimeMillis();

// 调用排序函数

sortMethod.invoke(null, params);

long endTime = System.currentTimeMillis();

assert isSorted(arr);

System.out.println(sortClass.getSimpleName() + " : " + (endTime - startTime) + "ms");

} catch (Exception e) {

e.printStackTrace();

}

}

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值