Java排序算法

Java排序算法
Java排序算法

排序一直以来都是让我很头疼的事,以前上《数据结构》打酱油去了,整个学期下来才勉强能写出个冒泡排序。由于下半年要准备工作了,也知道排序算法的重要性(据说是面试必问的知识点),所以又花了点时间重新研究了一下。

排序大的分类可以分为两种:内排序和外排序。在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序。下面讲的排序都是属于内排序。

内排序有可以分为以下几类:

(1)、插入排序:直接插入排序、二分法插入排序、希尔排序。

(2)、选择排序:简单选择排序、堆排序。

(3)、交换排序:冒泡排序、快速排序。

(4)、归并排序

(5)、基数排序

一、插入排序

?思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置,直到全部插入排序完为止。

?关键问题:在前面已经排好序的序列中找到合适的插入位置。

?方法:

–直接插入排序

–二分插入排序

–希尔排序

①直接插入排序(从后向前找到合适位置后插入)

1、基本思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。

2、实例

3、java实现

复制代码

1 package com.sort;

2

3 public class 直接插入排序{

4

5 public static void main(String[] args) {

6 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};

7 System.out.println("排序之前:");

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

9 System.out.print(a[i]+" ");

10 }

11 //直接插入排序

12 for (int i = 1; i < a.length; i++) {

13 //待插入元素

14 int temp = a[i];

15 int j;

16 /*for (j = i-1; j>=0 && a[j]>temp; j--) {

17 //将大于temp的往后移动一位

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

19 }*/

20 for (j = i-1; j>=0; j--) {

21 //将大于temp的往后移动一位

22 if(a[j]>temp){

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

24 }else{

25 break;

26 }

27 }

28 a[j+1] = temp;

29 }

30 System.out.println();

31 System.out.println("排序之后:");

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

33 System.out.print(a[i]+" ");

34 }

35 }

36

37 }

复制代码

4、分析

直接插入排序是稳定的排序。关于各种算法的稳定性分析可以参考https://www.360docs.net/doc/702384492.html,/Braveliu/archive/2013/01/15/2861201.html

文件初态不同时,直接插入排序所耗费的时间有很大差异。若文件初态为正序,则每个待插入的记录只需要比较一次就能够找到合适的位置插入,故算法的时间复杂度为O(n),这时最好的情况。若初态为反序,则第i个待插入记录需要比较i+1次才能找到合适位置插入,故时间复杂度为O(n2),这时最坏的情况。

直接插入排序的平均时间复杂度为O(n2)。

②二分法插入排序(按二分法找到合适位置插入)

1、基本思想:二分法插入排序的思想和直接插入一样,只是找合适的插入位置的方式不同,这里是按二分法找到合适的位置,可以减少比较的次数。

2、实例

3、java实现

复制代码

1 package com.sort;

2

3 public class 二分插入排序{

4 public static void main(String[] args) {

5 int[] a={49,38,65,97,176,213,227,49,78,34,12,164,11,18,1};

6 System.out.println("排序之前:");

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

8 System.out.print(a[i]+" ");

9 }

10 //二分插入排序

11 sort(a);

12 System.out.println();

13 System.out.println("排序之后:");

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

15 System.out.print(a[i]+" ");

16 }

17 }

18

19 private static void sort(int[] a) {

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

21 int temp = a[i];

22 int left = 0;

23 int right = i-1;

24 int mid = 0;

25 while(left<=right){

26 mid = (left+right)/2;

27 if(temp

28 right = mid-1;

29 }else{

30 left = mid+1;

31 }

32 }

33 for (int j = i-1; j >= left; j--) {

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

35 }

36 if(left != i){

37 a[left] = temp;

38 }

39 }

40 }

41 }

复制代码

4、分析

当然,二分法插入排序也是稳定的。

二分插入排序的比较次数与待排序记录的初始状态无关,仅依赖于记录的个数。当n 较大时,比直接插入排序的最大比较次数少得多。但大于直接插入排序的最小比较次数。算法的移动次数与直接插入排序算法的相同,最坏的情况为n2/2,最好的情况为n,平均移动次数为O(n2)。

③希尔排序

1、基本思想:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2

2、实例

3、java实现

复制代码

1 package com.sort;

2

3 //不稳定

4 public class 希尔排序{

5

6

7 public static void main(String[] args) {

8 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};

9 System.out.println("排序之前:");

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

11 System.out.print(a[i]+" ");

12 }

13 //希尔排序

14 int d = a.length;

15 while(true){

16 d = d / 2;

17 for(int x=0;x

18 for(int i=x+d;i

19 int temp = a[i];

20 int j;

21 for(j=i-d;j>=0&&a[j]>temp;j=j-d){

22 a[j+d] = a[j];

23 }

24 a[j+d] = temp;

25 }

26 }

27 if(d == 1){

28 break;

29 }

30 }

31 System.out.println();

32 System.out.println("排序之后:");

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

34 System.out.print(a[i]+" ");

35 }

36 }

37

38 }

复制代码

4、分析

我们知道一次插入排序是稳定的,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以希尔排序是不稳定的。

希尔排序的时间性能优于直接插入排序,原因如下:

(1)当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。

(2)当n值较小时,n和n2的差别也较小,即直接插入排序的最好时间复杂度O(n)

和最坏时间复杂度0(n2)差别不大。

(3)在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。

因此,希尔排序在效率上较直接插人排序有较大的改进。

希尔排序的平均时间复杂度为O(nlogn)。

二、选择排序

?思想:每趟从待排序的记录序列中选择关键字最小的记录放置到已排序表的最前位置,直到全部排完。

?关键问题:在剩余的待排序记录序列中找到最小关键码记录。

?方法:

–直接选择排序

–堆排序

①简单的选择排序

1、基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

2、实例

3、java实现

复制代码

1 package com.sort;

2

3 //不稳定

4 public class 简单的选择排序{

5

6 public static void main(String[] args) {

7 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};

8 System.out.println("排序之前:");

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

10 System.out.print(a[i]+" ");

11 }

12 //简单的选择排序

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

14 int min = a[i];

15 int n=i; //最小数的索引

16 for(int j=i+1;j

17 if(a[j]

18 min = a[j];

19 n = j;

20 }

21 }

22 a[n] = a[i];

23 a[i] = min;

24

25 }

26 System.out.println();

27 System.out.println("排序之后:");

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

29 System.out.print(a[i]+" ");

30 }

31 }

32

33 }

复制代码

4、分析

简单选择排序是不稳定的排序。

时间复杂度:T(n)=O(n2)。

②堆排序

1、基本思想:

堆排序是一种树形选择排序,是对直接选择排序的有效改进。

堆的定义下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。在这里只讨论满足前者条件的堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。完全二叉树可以很直观地表示堆的结构。堆顶为根,其它为左子树、右子树。

思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。

2、实例

初始序列:46,79,56,38,40,84

建堆:

交换,从堆中踢出最大数

依次类推:最后堆中剩余的最后两个结点交换,踢出一个,排序完成。

3、java实现

复制代码

1 package com.sort;

2 //不稳定

3 import java.util.Arrays;

4

5 public class HeapSort {

6 public static void main(String[] args) {

7 int[] a={49,38,65,97,76,13,27,49,78,34,12,64};

8 int arrayLength=a.length;

9 //循环建堆

10 for(int i=0;i

11 //建堆

12 buildMaxHeap(a,arrayLength-1-i);

13 //交换堆顶和最后一个元素

14 swap(a,0,arrayLength-1-i);

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

16 }

17 }

18 //对data数组从0到lastIndex建大顶堆

19 public static void buildMaxHeap(int[] data, int lastIndex){

20 //从lastIndex处节点(最后一个节点)的父节点开始

21 for(int i=(lastIndex-1)/2;i>=0;i--){

22 //k保存正在判断的节点

23 int k=i;

24 //如果当前k节点的子节点存在

25 while(k*2+1<=lastIndex){

26 //k节点的左子节点的索引

27 int biggerIndex=2*k+1;

28 //如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在

29 if(biggerIndex

30 //若果右子节点的值较大

31 if(data[biggerIndex]

32 //biggerIndex总是记录较大子节点的索引

33 biggerIndex++;

34 }

35 }

36 //如果k节点的值小于其较大的子节点的值

37 if(data[k]

38 //交换他们

39 swap(data,k,biggerIndex);

40 //将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值

41 k=biggerIndex;

42 }else{

43 break;

44 }

45 }

46 }

47 }

48 //交换

49 private static void swap(int[] data, int i, int j) {

50 int tmp=data[i];

51 data[i]=data[j];

52 data[j]=tmp;

53 }

54 }

复制代码

4、分析

堆排序也是一种不稳定的排序算法。

堆排序优于简单选择排序的原因:

直接选择排序中,为了从R[1..n]中选出关键字最小的记录,必须进行n-1次比较,然后在R[2..n]中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作。

堆排序可通过树形结构保存部分比较结果,可减少比较次数。

堆排序的最坏时间复杂度为O(nlogn)。堆序的平均性能较接近于最坏性能。由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。

三、交换排序

①冒泡排序

1、基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

2、实例

3、java实现

复制代码

1 package com.sort;

2

3 //稳定

4 public class 冒泡排序{

5 public static void main(String[] args) {

6 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};

7 System.out.println("排序之前:");

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

9 System.out.print(a[i]+" ");

10 }

11 //冒泡排序

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

13 for(int j = 0; j

14 //这里-i主要是每遍历一次都把最大的i个数沉到最底下去了,没有必要再替换了

15 if(a[j]>a[j+1]){

16 int temp = a[j];

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

18 a[j+1] = temp;

19 }

20 }

21 }

22 System.out.println();

23 System.out.println("排序之后:");

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

25 System.out.print(a[i]+" ");

26 }

27 }

28 }

复制代码

4、分析

冒泡排序是一种稳定的排序方法。

?若文件初状为正序,则一趟起泡就可完成排序,排序码的比较次数为n-1,且没有记录移动,时间复杂度是O(n)

?若文件初态为逆序,则需要n-1趟起泡,每趟进行n-i次排序码的比较,且每次比较都移动三次,比较和移动次数均达到最大值∶O(n2)

?起泡排序平均时间复杂度为O(n2)

②快速排序

1、基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。

2、实例

3、java实现

复制代码

package com.sort;

//不稳定

public class 快速排序{

public static void main(String[] args) {

int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};

System.out.println("排序之前:");

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

System.out.print(a[i]+" ");

}

//快速排序

quick(a);

System.out.println();

System.out.println("排序之后:");

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

System.out.print(a[i]+" ");

}

}

private static void quick(int[] a) {

if(a.length>0){

quickSort(a,0,a.length-1);

}

}

private static void quickSort(int[] a, int low, int high) {

if(low

int middle = getMiddle(a,low,high);

quickSort(a, 0, middle-1);

quickSort(a, middle+1, high);

}

}

private static int getMiddle(int[] a, int low, int high) {

int temp = a[low];//基准元素

while(low

//找到比基准元素小的元素位置

while(low=temp){

high--;

}

a[low] = a[high];

while(low

low++;

}

a[high] = a[low];

}

a[low] = temp;

return low;

}

}

复制代码

4、分析

快速排序是不稳定的排序。

快速排序的时间复杂度为O(nlogn)。

当n较大时使用快排比较好,当序列基本有序时用快排反而不好。

四、归并排序

1、基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有

序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

2、实例

3、java实现

复制代码

1 package com.sort;

2

3 //稳定

4 public class 归并排序{

5 public static void main(String[] args) {

6 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};

7 System.out.println("排序之前:");

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

9 System.out.print(a[i]+" ");

10 }

11 //归并排序

12 mergeSort(a,0,a.length-1);

13 System.out.println();

14 System.out.println("排序之后:");

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

16 System.out.print(a[i]+" ");

17 }

18 }

19

20 private static void mergeSort(int[] a, int left, int right) {

21 if(left

22 int middle = (left+right)/2;

23 //对左边进行递归

24 mergeSort(a, left, middle);

25 //对右边进行递归

26 mergeSort(a, middle+1, right);

27 //合并

28 merge(a,left,middle,right);

29 }

30 }

31

32 private static void merge(int[] a, int left, int middle, int right) {

33 int[] tmpArr = new int[a.length];

34 int mid = middle+1; //右边的起始位置

35 int tmp = left;

36 int third = left;

37 while(left<=middle && mid<=right){

38 //从两个数组中选取较小的数放入中间数组

39 if(a[left]<=a[mid]){

40 tmpArr[third++] = a[left++];

41 }else{

42 tmpArr[third++] = a[mid++];

43 }

44 }

45 //将剩余的部分放入中间数组

46 while(left<=middle){

47 tmpArr[third++] = a[left++];

48 }

49 while(mid<=right){

50 tmpArr[third++] = a[mid++];

51 }

52 //将中间数组复制回原数组

53 while(tmp<=right){

54 a[tmp] = tmpArr[tmp++];

55 }

56 }

57 }

复制代码

4、分析

归并排序是稳定的排序方法。

归并排序的时间复杂度为O(nlogn)。

速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。

五、基数排序

1、基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

2、实例

3、java实现

复制代码

1 package com.sort;

2

3 import java.util.ArrayList;

4 import java.util.List;

5 //稳定

6 public class 基数排序{

7 public static void main(String[] args) {

8 int[] a={49,38,65,97,176,213,227,49,78,34,12,164,11,18,1};

9 System.out.println("排序之前:");

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

11 System.out.print(a[i]+" ");

12 }

13 //基数排序

14 sort(a);

15 System.out.println();

16 System.out.println("排序之后:");

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

18 System.out.print(a[i]+" ");

19 }

20 }

21

22 private static void sort(int[] array) {

23 //找到最大数,确定要排序几趟

24 int max = 0;

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

26 if(max

27 max = array[i];

28 }

29 }

30 //判断位数

31 int times = 0;

32 while(max>0){

33 max = max/10;

34 times++;

35 }

36 //建立十个队列

37 List queue = new ArrayList();

38 for (int i = 0; i < 10; i++) {

39 ArrayList queue1 = new ArrayList();

40 queue.add(queue1);

41 }

42 //进行times次分配和收集

43 for (int i = 0; i < times; i++) {

44 //分配

45 for (int j = 0; j < array.length; j++) {

46 int x = array[j]%(int)Math.pow(10, i+1)/(int)Math.pow(10, i);

47 ArrayList queue2 = queue.get(x);

48 queue2.add(array[j]);

49 queue.set(x,queue2);

50 }

51 //收集

52 int count = 0;

53 for (int j = 0; j < 10; j++) {

54 while(queue.get(j).size()>0){

55 ArrayList queue3 = queue.get(j);

56 array[count] = queue3.get(0);

57 queue3.remove(0);

58 count++;

59 }

60 }

61 }

62 }

63 }

复制代码

4、分析

基数排序是稳定的排序算法。

基数排序的时间复杂度为O(d(n+r)),d为位数,r为基数。

总结:

一、稳定性:

稳定:冒泡排序、插入排序、归并排序和基数排序

不稳定:选择排序、快速排序、希尔排序、堆排序

二、平均时间复杂度

O(n^2):直接插入排序,简单选择排序,冒泡排序。

在数据规模较小时(9W内),直接插入排序,简单选择排序差不多。当数据较大时,冒泡排序算法的时间代价最高。性能为O(n^2)的算法基本上是相邻元素进行比较,基本上都是稳定的。

O(nlogn):快速排序,归并排序,希尔排序,堆排序。

其中,快排是最好的,其次是归并和希尔,堆排序在数据量很大时效果明显。

三、排序算法的选择

1.数据规模较小

(1)待排序列基本序的情况下,可以选择直接插入排序;

(2)对稳定性不作要求宜用简单选择排序,对稳定性有要求宜用插入或冒泡

2.数据规模不是很大

(1)完全可以用内存空间,序列杂乱无序,对稳定性没有要求,快速排序,此时要付出log(N)的额外空间。

(2)序列本身可能有序,对稳定性有要求,空间允许下,宜用归并排序

3.数据规模很大

(1)对稳定性有求,则可考虑归并排序。

(2)对稳定性没要求,宜用堆排序

4.序列初始基本有序(正序),宜用直接插入,冒泡

java程序员必知的十种程序算法

java程序员必学的十种程序算法 算法1:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。 算法步骤: 1 从数列中挑出一个元素,称为“基准”(pivot),

2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。 3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 算法2:堆排序算法

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 堆排序的平均时间复杂度为Ο(nlogn) 。 算法步骤: 创建一个堆H[0..n-1] 把堆首(最大值)和堆尾互换 3. 把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置 4. 重复步骤2,直到堆的尺寸为1 算法3:归并排序 归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 算法步骤:

JAVA数组的排序方法实例

冒泡排序法 1.public class SortArray_01 { 2. public static void main(String args[]) { 3. int[] array = { 14, 5, 86, 4, 12, 3, 21, 13, 11, 2, 55 }; // 创建一个初始化的一维数组array 4. System.out.println("未排序的数组:"); 5. for (int i = 0; i < array.length; i++) { // 遍历array数组中的元素 6. System.out.print(" " + array[i]); // 输出数组元素 7. if ((i + 1) % 5 == 0) // 每5个元素一行 8. System.out.println(); 9. } 10. int mid; // 定义一个中间变量, 起到临时存储数据的作用 11. for (int i = 0; i < array.length; i++) { // 执行冒 泡排序法 12. for (int j = i; j < array.length; j++) { 13. if (array[j] < array[i]) { 14. mid = array[i]; 15. array[i] = array[j]; 16. array[j] = mid; 17. } 18. } 19. } 20. System.out.println("\n使用冒泡法排序后的数组:"); 21. for (int i = 0; i < array.length; i++) { // 遍历排好序的array数组中的元素 22. System.out.print(" " + array[i]); // 输出数组元素 23. if ((i + 1) % 5 == 0) 24. System.out.println(); // 每5 个元素一行 25. } 26. } 27.} 数组递增排序

JAVA中运用数组的四种排序方法

JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法、冒泡法、选择排序法、插入排序法。 快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现。 冒泡法是运用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来。 选择排序法是将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组。 插入排序是选择一个数组中的数据,通过不断的插入比较最后进行排序。下面我就将他们的实现方法一一详解供大家参考。 <1>利用Arrays带有的排序方法快速排序 import java.util.Arrays; publicclass Test2{ publicstaticvoid main(String[] args){ int[] a={5,4,2,4,9,1}; Arrays.sort(a); //进行排序 for(int i: a){ System.out.print(i); } } } <2>冒泡排序算法 publicstaticint[] bubbleSort(int[] args){//冒泡排序算法 for(int i=0;iargs[j]){ int temp=args[i]; args[i]=args[j]; args[j]=temp; } } } return args; } <3>选择排序算法 publicstaticint[] selectSort(int[] args){//选择排序算法 for (int i=0;i

java中8大排序方法

Java程序员必知的8大排序本文主要详解了Java语言的8大排序的基本思想以及实例解读,详细请看下文8种排序之间的关系: 1,直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数 也是排好顺序的。如此反复循环,直到全部排好顺序。 (2)实例

(3)用java实现 1.package com.njue; 2. 3.public class insertSort { 4.public insertSort(){ 5. inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17, 18,23,34,15,35,25,53,51}; 6.int temp=0; 7.for(int i=1;i=0&&temp

Java各种排序算法

Java排序算法 1)分类: 1)插入排序(直接插入排序、希尔排序) 2)交换排序(冒泡排序、快速排序) 3)选择排序(直接选择排序、堆排序) 4)归并排序 5)分配排序(箱排序、基数排序) 所需辅助空间最多:归并排序 所需辅助空间最少:堆排序 平均速度最快:快速排序 不稳定:快速排序,希尔排序,堆排序。 1)选择排序算法的时候 1.数据的规模; 2.数据的类型; 3.数据已有的顺序 一般来说,当数据规模较小时,应选择直接插入排序或冒泡排序。任何排序算法在数据量小时基本体现不出来差距。考虑数据的类型,比如如果全部是正整数,那么考虑使用桶排序为最优。考虑数据已有顺序,快排是一种不稳定的排序(当然可以改进),对于大部分排好的数据,快排会浪费大量不必要的步骤。数据量极小,而起已经基本排好序,冒泡是最佳选择。我们说快排好,是指大量随机数据下,快排效果最理想。而不是所有情况。 3)总结: ——按平均的时间性能来分: 1)时间复杂度为O(nlogn)的方法有:快速排序、堆排序和归并排序,其中以快速排序为最好; 2)时间复杂度为O(n2)的有:直接插入排序、起泡排序和简单选择排序,其中以直接插入为最好,特别是对那些对关键字近似有序的记录序列尤为如此; 3)时间复杂度为O(n)的排序方法只有,基数排序。 当待排记录序列按关键字顺序有序时,直接插入排序和起泡排序能达到O(n)的时间复杂度;而对于快速排序而言,这是最不好的情况,此时的时间性能蜕化为O(n2),因此是应该尽量避免的情况。简单选择排序、堆排序和归并排序的时间性能不随记录序列中关键字的分布而改变。 ——按平均的空间性能来分(指的是排序过程中所需的辅助空间大小): 1)所有的简单排序方法(包括:直接插入、起泡和简单选择)和堆排序的空间复杂度为O(1); 2)快速排序为O(log n ),为栈所需的辅助空间; 3)归并排序所需辅助空间最多,其空间复杂度为O(n ); 4)链式基数排序需附设队列首尾指针,则空间复杂度为O(rd )。 ——排序方法的稳定性能: 1)稳定的排序方法指的是,对于两个关键字相等的记录,它们在序列中的相对位置,在排序之前和经过排序之后,没有改变。 2)当对多关键字的记录序列进行LSD方法排序时,必须采用稳定的排序方法。 3)对于不稳定的排序方法,只要能举出一个实例说明即可。 4)快速排序,希尔排序和堆排序是不稳定的排序方法。 4)插入排序: 包括直接插入排序,希尔插入排序。 直接插入排序:将一个记录插入到已经排序好的有序表中。 1, sorted数组的第0个位置没有放数据。

Java数据结构和算法笔记

Java数据结构和算法 第0讲综述 参考教材:Java数据结构和算法(第二版),[美] Robert lafore 1. 数据结构的特性 数据结构< 缺点 优点 数组插入快;如果知道下标,可以非常快地存取查找慢,删除慢,大小固定 有序数组比无序的数组查找快删除和插入慢,大小固定 提供后进先出方式的存取存取其他项很慢 < 栈 队列提供先进先出方式的存取存取其他项很慢 链表插入快,删除快— 查找慢 二叉树查找、插入、删除都快(如果树保持平衡)删除算法复杂 红-黑树查找、插入、删除都快;树总是平衡的算法复杂 算法复杂 2-3-4树` 查找、插入、删除都快;树总是平衡的;类 似的树对磁盘存储有用 哈希表如果关键字已知,则存储极快;插入快删除慢,如果不知道关键字则存 储很慢,对存储空间使用不充分堆插入、删除快;对大数据项的存取很快对其他数据项存取慢 对现实世界建模有些算法慢且复杂 》 图 2. 经典算法总结 查找算法:线性查找和二分查找 排序算法: 用表展示 ! 第一讲数组 1.Java中数组的基础知识 1)创建数组

在Java中把数组当作对象来对待,因此在创建数组时必须使用new操作符: < 一旦创建数组,数组大小便不可改变。 2)访问数组数据项 3)数组的初始化 当创建数组之后,除非将特定的值赋给数组的数据项,否则它们一直是特殊的null对 等效于下面使用new来创建数组并初始化: | 2.面向对象编程方式 1)使用自定义的类封装数组

| # !

子问题须与原始问题为同样的事,且更为简单; b. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。 1.三角数字 该数列中的首项为1,第n项是由第n-1项加n后得到的。 1)使用循环查找第n项

Java实现的常见排序算法

以下内容节选自Java私塾自编经典教材: 下面是Java实现的一些常见排序算法。 1:冒泡排序 对几个无序的数字进行排序,比较常用的方法是冒泡排序法。冒泡法排序是一个比较简单的排序方法,在待排序的数列基本有序的情况下排序速度较快。 基本思路:对未排序的各元素从头到尾依次比较相邻的两个元素是否逆序(与欲排顺序相反),若逆序就交换这两元素,经过第一轮比较排序后便可把最大(或最小)的元素排好,然后再用同样的方法把剩下的元素逐个进行比较,就得到了你所要的顺序。 可以看出如果有N个元素,那么一共要进行N-1轮比较,第I轮要进行N-I次比较。(如:有5个元素,则要进行5-1轮比较。第3轮则要进行5-3次比较) 示例如下: public class Test { public static void main(String[] args) { //需要排序的数组,目前是按照升序排列的 int a[] = new int[5]; a[0] = 3; a[1] = 4; a[2] = 1; a[3] = 5; a[4] = 2; //冒泡排序 for(int i=0;i a[j]){ int temp = a[j]; a[j] = a[i]; a[i] = temp; } } } //检测一下排序的结果 for(int i : a){ System.out.println("i="+i); } } } 运行结果: i=1 i=2

JAVA排序选择题

一、选择题 1.某内排序方法的稳定性是指()。 A.该排序算法不允许有相同的关键字记录B.该排序算法允许有相同的关键字记录 C.平均时间为0(n log n)的排序方法D.以上都不对 2.下面给出的四种排序法中()排序法是不稳定性排序法。 A.插入 B.冒泡 C.二路归并 D.堆积 3.下列排序算法中,其中()是稳定的。 A.堆排序,冒泡排序 B.快速排序,堆排序 C.直接选择排序,归并排序 D.归并排序,冒泡排序 4.稳定的排序方法是() A.直接插入排序和快速排序B.折半插入排序和起泡排序 C.简单选择排序和四路归并排序D.树形选择排序和shell排序 5.下列排序方法中,哪一个是稳定的排序方法?() A.直接选择排序B.二分法插入排序C.希尔排序D.快速排序 6.若要求尽可能快地对序列进行稳定的排序,则应选(A.快速排序B.归并排序C.冒泡排序)。 7.如果待排序序列中两个数据元素具有相同的值,在排序前后它们的相互位置发生颠倒,则称该排序算法是 不稳定的。()就是不稳定的排序方法。 A.起泡排序B.归并排序C.Shell排序D.直接插入排序E.简单选择排序8.若要求排序是稳定的,且关键字为实数,则在下列排序方法中应选()排序为宜。 A.直接插入B.直接选择C.堆D.快速E.基数 9.若需在O(nlog2n)的时间内完成对数组的排序,且要求排序是稳定的,则可选择的排序方法是()。 A.快速排序 B.堆排序 C.归并排序 D.直接插入排序 10.下面的排序算法中,不稳定的是() A.起泡排序 B.折半插入排序 C.简单选择排序 D.希尔排序 E.基数排序 F.堆排序。 11.下列内部排序算法中: A.快速排序B.直接插入排序C.二路归并排序D.简单选择排序E.起泡排序F.堆排序(1)其比较次数与序列初态无关的算法是()(2)不稳定的排序算法是() (3)在初始序列已基本有序(除去n个元素中的某k个元素后即呈有序,k<

Java常用基本算法

4.1 算法 前面我们已经讲过,程序=数据结构+算法。 什么是算法?对一个现有的问题我们采取的解决过程及方法,即为算法。一个用算法实现的程序会耗费两种资源:处理时间和内存。 算法的效率分析标准: 时间复杂度 空间复杂度 简单性和清晰性 对于时间复杂度,可以通过System.currentTimeMillis()方法来测试。例如:public class Test { public static void main(String args[]) { System.out.println(System.currentTimeMillis()); fun(); System.out.println(System.currentTimeMillis()); } public static void fun() { double a = 0; for(int i = 0; i < 10000; i++) for(int j = 0; j < 10000; j++) for(int k = 0; k < 100; k++) a++; } } 前后两次获得当前系统时间的差值就是运行所消耗的时间(毫秒为单位)。 通过System.currentTimeMillis()方法来测试的缺点: a.不同的平台执行的时间不同 b.有些算法随着输入数据的加大,测试时间会变得不切实际! 4.2 查找 4.2.1 查找之线性查找(直接查找) 算法思路:从数组的第一个元素开始查找,并将其与查找值比较,如果相等则停止,否则继续下一个元素查找,直到找到匹配值。 注意:被查找的数组中的元素可以是无序的、随机的。 实例: import java.util.*; public class Demo1 { public static void main(String args[]) {

冒泡排序法、选择排序法、插入排序法(java案例详解)

1.冒泡排序法 /** *功能:冒泡排序法 *思想:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的排序码, *,若发现逆序这交换,使得排序码较小的元素逐渐从后部移向前部(从下标较大的单元移向下标) *较小的单元,,就像水底下的气泡一样逐渐向上冒。 *作者:徐守威 */ package com.xushouwei; public class T4 { /** *@param args */ public static void main(String[] args) { // TODO Auto-generated method stub int arr1[]={1,6,0,-1,9,-100,90}; //开始排序,创建一个Bubble类 Bubble bubble=new Bubble(); bubble.sort(arr1); //输出最后结果 for(int i=0;i

//排序方法 public void sort(int arr[]) { //第一层循环用来指定排序的次数 //定义一个临时变量来存放交换的值 int temp=0; for(int i=0;iarr[j+1]) { //交换位置 temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } } } 2.选择排序法 /** *功能:选择排序法 *思想:第一次从R[0]-R[N-1]中选取最小值,与R[0]交换,第二次从 R[1]-R[N-1]中选取最小值,与R[1]交换, *第三次从R[2]-R[N-1]中选取最小值,与R[2]交换...第i次从 R[i]-R[N-1]中选取最小值,与R[i-1]交换, *第n-1次从R[n-2]-R[N-1]中选取最小值,与R[n-2]交换,总共通过n-1

十 大 经 典 排 序 算 法 总 结 超 详 细

数据结构七种排序算法讲解及其Java实现 数据结构七种排序算法讲解及其Java实现冒泡排序算法描述Java代码时间复杂度选择排序算法描述Java代码时间复杂度插入排序算法描述Java代码时间复杂度希尔排序算法描述Java代码时间复杂度归并排序算法描述Java代码时间复杂度快速排序算法描述Java代码时间复杂度堆排序算法描述Java代码时间复杂度总结 数据结构的排序算法共有十种,本文仅给出其中七种算法,有空的话会把剩下的三种(基数排序、计数排序、桶排序)补全。 本文代码使用的测试样例: int[] arr = {1,2,3,4,5}; int[] arr1 = {5,4,3,2,1}; int[] arr2 = {1,5,3,4,2}; 本文对于需要排序的数组为a,类型为整形数组,假设其长度为n,所以数组下标范围为[0, n-1] 冒泡排序 冒泡排序可以说是我们最基础的排序方式了,可以说是排序题的暴力解法 算法描述 核心思想: 每轮都把最大的元素移到最右边,再开始下一轮,从剩下的元素中继续挑选最大值继续移动到右边,这样的操作重复n轮,即可完成排序(其

实只要n-1次就够了,最后一次只剩下一个元素) 具体过程: 首先将数组从a[0]到a[n-1],通过一次次比较,把最大的元素移到最右边的a[n-1],此时a[0]到a[n-1]的最大的元素已经放到a[n-1] 第二次将数组从a[0]到a[n-2],通过一次次比较,把最大的元素移到最右边的a[n-2],此时a[0]到a[n-1]的第二大的元素已经放到a[n-1] 第三次将数组从a[0]到a[n-3],… Java代码 public int[] bubbleSort(int[] array) { for (int i = 0; i array.length; i++) { boolean isSwapped = false; for (int j = 0; j array.length - 1 - i; j++) { if (array[j] array[j+1]) { int tmp = array[j]; array[j] = array[j+1]; array[j+1] = tmp; isSwapped = true; if (!isSwapped) { return array; 时间复杂度 最好情况O(n), 最坏情况O(n2), 平均情况O(n2) 最好情况便是如[1,2,3,4,5]这样的情况,外层循环只需要执行一次,

Java排序算法

六归并排序 算法思想是每次把待排序列分成两部分,分别对这两部分递归地用归并排序,完成后把这两个子部分合并成一个 序列。 归并排序借助一个全局性临时数组来方便对子序列的归并,该算法核心在于归并。 package algorithms; import https://www.360docs.net/doc/702384492.html,ng.reflect.Array; /** * @author yovn * */ public class MergeSorter> extends Sorter { /* (non-Javadoc) * @see algorithms.Sorter#sort(E[], int, int) */ @SuppressWarnings("unchecked") @Override public void sort(E[] array, int from, int len) { if(len<=1)return; E[] temporary=(E[])Array.newInstance(array[0].getClass(),len); merge_sort(array,from,from+len-1,temporary); } private final void merge_sort(E[] array, int from, int to, E[] temporary) { if(to<=from) { return; } int middle=(from+to)/2; merge_sort(array,from,middle,temporary);

merge_sort(array,middle+1,to,temporary); merge(array,from,to,middle,temporary); } private final void merge(E[] array, int from, int to, int middle, E[] temporary) { int k=0,leftIndex=0,rightIndex=to-from; System.arraycopy(array, from, temporary, 0, middle-from+1); for(int i=0;i

java排序算法大全

java排序算法大全 为了便于管理,先引入个基础类: package algorithms; public abstract class Sorter> { public abstract void sort(E[] array,int from ,int len); public final void sort(E[] array) { sort(array,0,array.length); } protected final void swap(E[] array,int from ,int to) { E tmp=array[from]; array[from]=array[to]; array[to]=tmp; } } 一插入排序 该算法在数据规模小的时候十分高效,该算法每次插入第K+1到前K个有序数组中一个合适位置,K从0开始到N-1,从而完成排序: package algorithms; /** * @author yovn */ public class InsertSorter> extends Sorter { /* (non-Javadoc) * @see algorithms.Sorter#sort(E[], int, int) */ public void sort(E[] array, int from, int len) { E tmp=null; for(int i=from+1;ifrom;j--) { if(https://www.360docs.net/doc/702384492.html,pareTo(array[j-1])<0) { array[j]=array[j-1]; } else break;

java排序123

java排序123 为了便于管理,先引入个基础类: package algorithms; public abstract class Sorter> { public abstract void sort(E[] array,int from ,int len); public final void sort(E[] array) { sort(array,0,array.length); } protected final void swap(E[] array,int from ,int to) { E tmp=array[from]; array[from]=array[to]; array[to]=tmp; } } 一插入排序 该算法在数据规模小的时候十分高效,该算法每次插入第K+1到前K个有序数组中一个合适位置,K从0开始到N-1,从而完成排序: package algorithms; /** * @author yovn */ public class InsertSorter> extends Sorter { /* (non-Javadoc) * @see algorithms.Sorter#sort(E[], int, int) */ public void sort(E[] array, int from, int len) { E tmp=null; for(int i=from+1;ifrom;j--) { if(https://www.360docs.net/doc/702384492.html,pareTo(array[j-1])<0) { array[j]=array[j-1]; } else break;

JAVA常用4种排序方法

JAVA常用4种排序方法 JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法、冒泡法、选择排序法、插入排序法。 快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现。 冒泡法是运用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来。 选择排序法是将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组。 插入排序是选择一个数组中的数据,通过不断的插入比较最后进行排序。下面我就将他们的实现方法一一详解供大家参考。 <1>利用Arrays带有的排序方法快速排序 复制代码 1 import java.util.Arrays; 2 public class Test2{ 3 public static void main(String[] args){ 4 int[] a={5,4,2,4,9,1}; 5 Arrays.sort(a); //进行排序 6 for(int i: a){ 7 System.out.print(i); 8 } 9 } 10 } 复制代码 <2>冒泡排序算法 复制代码 1 public static int[] bubbleSort(int[] args){//冒泡排序算法 2 for(int i=0;iargs[j]){ 5 int temp=args[i]; 6 args[i]=args[j]; 7 args[j]=temp; 8 } 9 } 10 } 11 return args; 12 } 复制代码

排序算法比较_java课程设计_刘阳辉

目录 一、课程设计目的 (02) 二、设计内容和要求 (02) 三、程序开发环境 (02) 四、程序内容 (02) 五、设计原理 (02) 六、技术亮点 (02) 七、程序流程图 (03) 八、程序模拟运 (03) 九、程序代码 (05) 十、设计体会 (18)

一、设计目的 1.掌握各种排序的基本思想。 2.掌握各种排序方法的算法实现。 3.掌握各种排序方法的优劣分析及花费的时间的计算。 4.掌握各种排序方法所适应的不同场合。 二、设计内容和要求 利用随机函数产生30000个随机整数,利用插入排序、起泡排序、选择排序、快速排序、堆排序、归并排序等排序方法进行排序,并统计每一种排序上机所花费的时间。 三、开发环境 开发平台:windows XP 开发环境:MyEclipse 8.5 jdk 6.0 开发语言:java 四、程序内容 第一部分:显示用户界面; 第二部分:输入希望产生的随机数的数量; 第三部分:点击获取数据按钮,根据用户输入的随机数的数量产生相应的随机数,并显示出来; 第四部分:点击排序按钮,将产生的随机数进行排序后重新显示出来,并计算显示每种排序算法所用的想用时间。 五、设计原理 首先使用随机函数产生相应的随机数并保存在整型数组中,并将整型数组里面的元素显示到用户界面,点击排序按钮后,将整形数组以传地址的方式传到排序类中进行排序,排序完后将再次显示整形数组里面的所有元素。 六、技术亮点 1.为提高程序效率,在使用七种排序算法时采用多线程技术同时执行七个排序线程,从而提高程序执行效率; 2.自定义动态数组,在程序执行的过程中根据用户输入的随机数的量来产生相应大小的整形数组; 3.更人性化的随机数,根据用户输入的随机数的数量(max)来产生的随机数的范围为0至max;

JAVA数组入门与选择排序算法讲义

数组与选择排序算法 一、概念 数组是一种数据结构,是用来存储同一数据类型的数值的集合。通过数组的下标可以访问数组的每一个元素。例如,整型数组a[i]用来存储整型数据,i就是下标。数组的下标是从0开始计数的。 在声明数组的时候,需要指明数组的数据类型和数组变量的名字。例如,下面就是声明整型数组的格式。 int a[]或int[]a 这条语句只是声明了数组,但是还没有对数组分配内存,即没有进行实例化。如果需要实例化,则必须使用new关键字。例如 int a[]=new int[100] 该语句声明了整型数组,且数组中可以存储100个整型数据。 只有对数组进行了实例化,才可以对数组的每个元素进行赋值。例如,a[3]=5,表示给数组的第4个元素赋值。 小技巧:可以使用循环给数组元素全部或部分元素赋值,例如: for(int i=0;i<=99;i++) a[i]=i; 注意1:如果试图访问元素a[100],则发生数组越界的异常,显示信息的关键字为: array index out of bounds 注意2:Java中允许长度为0的数组的存在。例如在编写一个返回值为数组的方法时,如果返回值为为空,则允许返回长度(即数组元素)为0的数组。例如:new int[0] 二、数组的初始化即匿名数组 在Java中提供了一种创建数组并同时实例化的操作方式,这是一种数组实例化的简化形式。例如: int a[]={3,4,6,11,12} 用这种形式,还可以创建匿名数组,例如: new int[]{3,4,6,11,12} 用这种方式进行数组的实例化,数组元素的个数就是大括号中元素的个数。 小技巧:用这种方式可以在不增加变量名的情况下重新初始化一个数组。例如,下面的两种格式,效果是一样的。 格式一:传统的变量赋值格式 int a[],b[] a=new int[]{4,7,9,10,33}; b=a; 格式二:简化形式 int b[]; b=new int[]{4,7,9,10,33}; 三、for each循环与数组 从JDK5.0开始,引入了一种新的循环格式,即fo reach循环,这种循环常常与数组一起使用。下面是格式:

归并排序算法的原理及JAVA实现

归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为: 1)划分子表 2)合并半子表 首先我们来讨论归并算法,归并算法将一系列数据放到一个向量中,索引范围为[first,last],这个序列由两个排好序的子表构成,以索引终点(mid)为分界线,以下面一个序列为例 7,10,19,25,12,17,21,30,48 这样的一个序列中,分为两个子序列 7,10,19,25 和 12,17,21,30,48,如下图所示: 再使用归并算法的时候的步骤如下: 第一步:比较v[indexA]=7和v[indexB]=12,将较小的v[indexA]取出来放到临时向量tempArray中,然后indexA加1 第二步:比较v[indexA]=10和v[indexB]=12,将较小的10放到临时变量tempArray中,然后indexA++;

第三步:比较v[indexA]=19与v[indexB]=12,将较小的12存放到临时变量tempArray中,然后indexB++; 第四步到第七步:按照以上规则,进行比对和存储,得到如下结果: 最后一步:将子表b中剩余项添加到临时向量tempArray中 然后将临时变量中的值按照索引位置,拷贝回向量v中,就完成了对向量v 的归并排序 Java实现代码: package com.sort.merge; public class Merge { /** * 分治法,自顶向下,递归分割数组,最终归并 */ public static void merge(int[] arr,int start,int end){ if(start

如何击败JAVA自带排序算法

如何击败Java自带排序算法的 Java8对自带的排序算法进行了很好的优化。对于整形和其他的基本类型,Arrays.sort()综合利用了双枢轴快速排序、归并排序和启发式插入排序。这个算法是很强大的,可以在很多情况下通用。针对大规模的数组还支持更多变种。我拿自己仓促写的排序算法跟Java自带的算法进行了对比,看看能不能一较高下。这些实验包含了对特殊情况的处理。 首先,我编写了一个经典的快速排序算法。这个算法通过计算样本的平均值来估计整个数组的中心点,然后用作初始枢轴。 我借鉴了一些Java的思路来适当改进我的快速排序,修改后的算法在对小数组进行排序的时候直接调用了插入排序。在这种情况下,我的排序算法和Java的排序算法可以达到相同的运行时间量级。Wild&al指出,如果排序数组有很多的重复数据,标准的快速排序会比双枢轴的快速排序要快。我没有尝试任何字节或汇编级别的分析和优化。在大部分的问题中,我的版本的优化程序都远远不能跟Java系统程序相提并论。 我一直都想测试脑海里的一个简单的排序算法,我称之为Bleedsort。这是一个分布式算法,它通过样本抽样方法对要排序的数组进行分布估计,根据估计结果把数据分配到相应的一个临时的数组里(如图1所示),并重写这个初始的数组。这是一个预处理过程,然后再应用其他的排序算法分别进行排序。在我的测试中,我使用了我编写的快速排序版本。如果使用合并排序应该会有更好的结果,因为合并排序被广泛应用在高度结构化的数组中。为了计算简单,我只测试了分布均匀的数据。 Bleedsort在遇到相同的数据的时候都会放到右边,所以此算法在排序相对一致(译者注:会有很多重复数据)的数组的时候表现很差。所以我需要对排序的数组进行样本估计,当重复数很多的情况下应避免使用Bleedsort算法。 我很清楚,Bleedsort算法在内存空间使用方面没办法跟归并排序(快速排序)相提并论,临时数组也比原来的数组要大四倍左右。同时其他的一些分布排序算法,比如Flashsort,在这方面也表现得要好很多。 图1Bleedsort举例说明 我运用JMH来作为测试基准。为了简单起见,我就用整形数组进行测试。在1000.000到10.000.0000数量级的均匀分布的数组中,我的算法表现的最好。尽管我写的快速排序算法

相关主题
相关文档
最新文档