java list 排序性能_Java常用排序算法及性能测试集合

/** SortUtil.java

* Version 1.0.0

* Created on 2017年9月3日

* Copyright ReYo.Cn*/

packagereyo.sdk.utils.test.sort;/*** 创 建 人:AdministratorReyoAut

* 创建时间:2017年9月3日 上午7:41:36

*

*@authorReYo

*@version1.0*/

importjava.lang.reflect.Method;importjava.util.Arrays;importjava.util.Date;/*** Java常用排序算法及性能测试集合

*

* 本程序集合涵盖常用排序算法的编写,并在注释中配合极其简单的特例讲解了各种算法的工作原理,以方便理解和吸收;

* 程序编写过程中吸收了很多维基百科和别人blog上面的例子,并结合自己的思考,选择或改进一个最容易让人理解的写法。*/

public classSortUtil {//被测试的方法集合

static String[] methodNames = new String[] { "bubbleSort", "bubbleSortAdvanced", "bubbleSortAdvanced2","selectSort", "insertSort", "insertSortAdvanced", "insertSortAdvanced2", "binaryTreeSort", "shellSort","shellSortAdvanced", "shellSortAdvanced2", "mergeSort", "quickSort", "heapSort"};public static void main(String[] args) throwsException {//correctnessTest();

performanceTest(20000);

}/*** 正确性测试

* 简单地测试一下各个算法的正确性

* 只是为了方便观测新添加的算法是否基本正确;

*@throwsException 主要是反射相关的Exception;
*/

public static void correctnessTest() throwsException {int len = 10;int[] a = new int[len];for (int i = 0; i < methodNames.length; i++) {for (int j = 0; j < a.length; j++) {

a[j]= (int) Math.floor(Math.random() * len * 2);

}

Method sortMethod= null;

sortMethod= SortUtil.class.getDeclaredMethod(methodNames[i], a.getClass());

Object o= sortMethod.invoke(null, a);

System.out.print(methodNames[i]+ " : ");if (o == null) {

System.out.println(Arrays.toString(a));

}else{//兼顾mergeSort,它的排序结果以返回值的形式出现;

System.out.println(Arrays.toString((int[]) o));

}

}

}/*** 性能测试

* 数组长度用参数len传入,每个方法跑20遍取耗时平均值;

*@paramlen 数组长度 建议取10000以上,否则有些算法会显示耗时为0;

*@throwsException 主要是反射相关的Exception;
*/

public static void performanceTest(int len) throwsException {int[] a = new int[len];int times = 20;

System.out.println("Array length: " +a.length);for (int i = 0; i < methodNames.length; i++) {

Method sortMethod= null;

sortMethod= SortUtil.class.getDeclaredMethod(methodNames[i], a.getClass());int totalTime = 0;for (int j = 0; j < times; j++) {for (int k = 0; k < len; k++) {

a[k]= (int) Math.floor(Math.random() * 20000);

}long start = newDate().getTime();

sortMethod.invoke(null, a);long end = newDate().getTime();

totalTime+= (end -start);

}

System.out.println(methodNames[i]+ " : " + (totalTime / times) + " ms");//System.out.println(Arrays.toString(a));

}

}/*** 最原始的冒泡交换排序;

* 两层遍历,外层控制扫描的次数,内层控制比较的次数;

* 外层每扫描一次,就有一个最大的元素沉底;所以内层的比较次数将逐渐减小;

* 时间复杂度: 平均:O(n^2),最好:O(n);最坏:O(n^2);

* 空间复杂度: O(1);*/

public static void bubbleSort(int[] a) {for (int i = 0; i < a.length; i++) {for (int j = 0; j < a.length - i - 1; j++) {if (a[j] > a[j + 1]) {int tmp =a[j];

a[j]= a[j + 1];

a[j+ 1] =tmp;

}

}

}

}/*** 改进的冒泡法

* 改进之处在于:设一个标志位,如果某趟跑下来,没有发生交换,说明已经排好了;
*/

public static void bubbleSortAdvanced(int[] a) {int k = a.length - 1;boolean flag = true;while(flag) {

flag= false;for (int i = 0; i < k; i++) {if (a[i] > a[i + 1]) {int tmp =a[i];

a[i]= a[i + 1];

a[i+ 1] =tmp;//有交换则继续保持标志位;

flag = true;

}

}

k--;

}

}/*** 改进的冒泡法2

* 改进之处在于吸收上面的思想(没有交换意味着已经有序),如果局部的已经是有序的,则后续的比较就不需要再比较他们了。

* 比如:3142 5678,假如刚刚做完了2和4交换之后,发现这趟比较后续再也没有发生交换,则后续的比较只需要比到4即可;

* 该算法就是用一个标志位记录某趟最后发生比较的地点;
*/

public static void bubbleSortAdvanced2(int[] a) {int flag = a.length - 1;intk;while (flag > 0) {

k=flag;

flag= 0;for (int i = 0; i < k; i++) {if (a[i] > a[i + 1]) {int tmp =a[i];

a[i]= a[i + 1];

a[i+ 1] =tmp;//有交换则记录该趟最后发生比较的地点;

flag = i + 1;

}

}

}

}/*** 插入排序

*

* 关于插入排序,这里有几个约定,从而可以快速理解算法:

* i: 无序表遍历下标;i

* j: 有序表遍历下表;0<=j

* a[i]:表示当前被拿出来做插入排序的无序表头元素;

* a[j]:有序表中的任意元素;

*

* 算法关键点:把数组分割为a[0~i-1]有序表,a[i~n-1]无序表;每次从无序表头部取一个,

* 把它插入到有序表适当的位置,直到无序表为空;

* 初始时,a[0]为有序表,a[1~n-1]为无序表;

*

* 时间复杂度: 平均:O(n^2),最好:O(n);最坏:O(n^2);

* 空间复杂度: O(1);*/

public static void insertSort(int[] a) {//从无序表头开始遍历;

for (int i = 1; i < a.length; i++) {intj;//拿a[i]和有序表元素依次比较,找到一个恰当的位置;

for (j = i - 1; j >= 0; j--) {if (a[j]

}

}//如果找到恰当的位置,则从该位置开始,把元素朝后移动一格,为插入的元素腾出空间;

if (j != (i - 1)) {int tmp =a[i];intk;for (k = i - 1; k > j; k--) {

a[k+ 1] =a[k];

}

a[k+ 1] =tmp;

}

}

}/*** 改进的插入排序1

* 改进的关键在于:首先拿无序表头元素a[i]和有序表尾a[i-1]比较,

* 如果a[i]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值