排序从入门到精通

简介: 排序从入门到精通

 

普通排序

1.1 Comparable接口介绍

1.2 冒泡排序

1.3 选择排序

1.4 插入排序

二、高级排序

2.1希尔排序

2.2.2 归并排序

2.3 快速排序

2.4 排序的稳定性

一,对数组进行排序:通常情况下我们可以使用Array.sort()来对数组进行排序,有以下3种情况:

二,对自定义类进行排序当我们处理自定义类型的排序时,一般将自定义类放在List种,之后再进行排序

三. Arrays.fill()


普通排序

在我们的程序中,排序是非常常见的一种需求,提供一些数据元素,把这些数据元素按照一定的规则进行排序。比

如查询一些订单,按照订单的日期进行排序;再比如查询一些商品,按照商品的价格进行排序等等。所以,接下来

我们要学习一些常见的排序算法。

java的开发工具包jdk中,已经给我们提供了很多数据结构与算法的实现,比如ListSetMapMath等等,都

是以API的方式提供,这种方式的好处在于一次编写,多处使用。我们借鉴jdk的方式,也把算法封装到某个类中,

那如果是这样,在我们写java代码之前,就需要先进行API的设计,设计好之后,再对这些API进行实现。

就比如我们先设计一套API如下:

然后再使用java代码去实现它。以后我们讲任何数据结构与算法都是以这种方式讲解

1.1 Comparable接口介绍

由于我们这里要讲排序,所以肯定会在元素之间进行比较,而Java提供了一个接口Comparable就是用来定义排序

规则的,在这里我们以案例的形式对Comparable接口做一个简单的回顾。

需求:

1.定义一个学生类Student,具有年龄age和姓名username两个属性,并通过Comparable接口提供比较规则;

2.定义测试类Test,在测试类Test中定义测试方法Comparable getMax(Comparable c1,Comparable c2)完成测试

1. public class Student implements Comparable<Student>{
2. private String username;
3. private int age;
4. 
5. public String getUsername() {
6. return username;
7.     }
8. 
9. public void setUsername(String username) {
10. this.username = username;
11.     }
12. 
13. public int getAge() {
14. return age;
15.     }
16. 
17. public void setAge(int age) {
18. this.age = age;
19.     }
20. @Override
21. public String toString(){
22. return "Student{'"+username+'\''+",age="+age+'}';
23.     }
24. @Override
25. public int compareTo(Student o){
26. return this.getAge()-o.getAge();
27.     }
28. 
29. }
30. class Test{
31. public static void main(String[] args) {
32. Student stu1=new Student();
33.         stu1.setUsername("zhangsan");
34.         stu1.setAge(17);
35. Student stu2=new Student();
36.          stu2.setUsername("list");
37.         stu2.setAge(19);
38. Comparable max=getMax(stu1,stu2);
39. System.out.println(max);
40.     }
41. public static Comparable getMax(Comparable c1,Comparable c2){
42.         int cmp=c1.compareTo(c2);
43. if(cmp>=0)return c1;
44. else return c2;
45. 
46.     }
47. 
48. }

1.2 冒泡排序

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。

需求:

排序前:{4,5,6,3,2,1}

排序后:{1,2,3,4,5,6}

排序原理:

1. 比较相邻的元素。如果前一个元素比后一个元素大,就交换这两个元素的位置。

2. 对每一对相邻元素做同样的工作,从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大

值。

 

1. import java.util.Arrays;
2. 
3. public class Bubble {
4. public static void sort(Comparable[] a) {
5. for (int i = a.length - 1; i > 0; i--) {
6. for (int j = 0; j < i; j++) {
7. if (greater(a[j], a[j + 1])) {
8.                     exch(a, j, j + 1);
9.                 }
10.             }
11.         }
12. 
13.     }
14. 
15. private static boolean greater(Comparable v, Comparable w) {
16. return v.compareTo(w) > 0;
17.     }
18. 
19. private static void exch(Comparable[] a, int i, int j) {
20. Comparable t = a[i];
21.         a[i] = a[j];
22.         a[j] = t;
23.     }
24. }
25. 
26. 
27. class Test{
28. public static void main(String[] argc){
29.      Integer[] a={4,5,3,2,1};
30.         Bubble.sort(a);
31.         System.out.println(Arrays.toString(a));
32.     }
33. }

冒泡排序的时间复杂度分析 冒泡排序使用了双层for循环,其中内层循环的循环体是真正完成排序的代码,所以,

我们分析冒泡排序的时间复杂度,主要分析一下内层循环体的执行次数即可。

在最坏情况下,也就是假如要排序的元素为{6,5,4,3,2,1}逆序,那么:

元素比较的次数为:

(N-1)+(N-2)+(N-3)+...+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

元素交换的次数为:

(N-1)+(N-2)+(N-3)+...+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

总执行次数为:

(N^2/2-N/2)+(N^2/2-N/2)=N^2-N;

按照大O推导法则,保留函数中的最高阶项那么最终冒泡排序的时间复杂度为O(N^2).

1.3 选择排序

选择排序是一种更加简单直观的排序方法。

需求:

排序前:{4,6,8,7,9,2,10,1}

排序后:{1,2,4,5,7,8,9,10}

排序原理:

1.每一次遍历的过程中,都假定第一个索引处的元素是最小值,和其他索引处的值依次进行比较,如果当前索引处

的值大于其他某个索引处的值,则假定其他某个索引出的值为最小值,最后可以找到最小值所在的索引

2.

交换第一个索引处和最小值所在的索引处的值

 

1. import java.util.Arrays;
2. 
3. public class Selection {
4. public static void sort(Comparable[] a){
5. for(int i=0;i<=a.length-2;i++){
6. int minIndex=i;
7. for(int j=i+1;j<a.length;j++){
8. if(greater(a[minIndex],a[j])){
9.                 minIndex=j;
10.             }
11.         }
12.         exch(a,i,minIndex);
13.        }
14.    }
15. private static boolean greater(Comparable v,Comparable w){
16. return v.compareTo(w)>0;
17.   }
18. public static void exch(Comparable[] a,int i,int j){
19.    Comparable t=a[i];
20.    a[i]=a[j];
21.    a[j]=t;
22.    }
23.    }
24. class Test2{
25. public static void main(String[] args) {
26.         Integer[] a={4,6,8,9,2,10,1};
27.         Selection.sort(a);
28.         System.out.println(Arrays.toString(a));
29. 
30.     }
31. 
32. 
33. }

选择排序的时间复杂度分析:

选择排序使用了双层for循环,其中外层循环完成了数据交换,内层循环完成了数据比较,所以我们分别统计数据

交换次数和数据比较次数:

数据比较次数:

(N-1)+(N-2)+(N-3)+...+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

数据交换次数:

N-1

时间复杂度:N^2/2-N/2+N-1=N^2/2+N/2-1;

根据大O推导法则,保留最高阶项,去除常数因子,时间复杂度为O(N^2);

1.4 插入排序

插入排序(Insertion sort)是一种简单直观且稳定的排序算法。

插入排序的工作方式非常像人们排序一手扑克牌一样。开始时,我们的左手为空并且桌子上的牌面朝下。然后,我

们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在

手中的每张牌进行比较,如下图所示:

 

需求:

排序前:{4,3,2,10,12,1,5,6}

排序后:{1,2,3,4,5,6,10,12}

排序原理:

1.把所有的元素分为两组,已经排序的和未排序的;

2.找到未排序的组中的第一个元素,向已经排序的组中进行插入;

3.倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待

插入元素放到这个位置,其他的元素向后移动一位;

 

1. import java.lang.reflect.Array;
2. import java.util.Arrays;
3. 
4. public class Insertion {
5. public static void sort(Comparable[] a){
6. for(int i=1;i<a.length;i++){
7. for(int j=i;j>0;j--){
8. if(greater(a[j-1],a[j])){
9.                 exch(a,j-1,j);
10.             }else {
11. break;
12.             }
13.         }
14.     }
15. 
16. 
17.     }
18. private static boolean greater(Comparable v,Comparable w){
19. return v.compareTo(w)>0;
20.   }
21. private static void exch(Comparable[] a,int i,int j){
22.      Comparable t=a[i];
23.      a[i]=a[j];
24.      a[j]=t;
25.     }
26. }
27. class Test3{
28. public static void main(String[] args) {
29.         Integer[] a={45,4565,2,3,8,2};
30.         Insertion.sort(a);
31.         System.out.println(Arrays.toString(a));
32. 
33.     }
34. }
35. 
36. 
37. 
38.

插入排序的时间复杂度分析

插入排序使用了双层for循环,其中内层循环的循环体是真正完成排序的代码,所以,我们分析插入排序的时间复

杂度,主要分析一下内层循环体的执行次数即可。

最坏情况,也就是待排序的数组元素为{12,10,6,5,4,3,2,1},那么:

比较的次数为:

(N-1)+(N-2)+(N-3)+...+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

交换的次数为:

(N-1)+(N-2)+(N-3)+...+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

总执行次数为:

(N^2/2-N/2)+(N^2/2-N/2)=N^2-N;

按照大O推导法则,保留函数中的最高阶项那么最终插入排序的时间复杂度为O(N^2)

二、高级排序

之前我们学习过基础排序,包括冒泡排序,选择排序还有插入排序,并且对他们在最坏情况下的时间复杂度做了分

析,发现都是O(N^2),而平方阶通过我们之前学习算法分析我们知道,随着输入规模的增大,时间成本将急剧上

升,所以这些基本排序方法不能处理更大规模的问题,接下来我们学习一些高级的排序算法,争取降低算法的时间

复杂度最高阶次幂。

2.1希尔排序

希尔排序是插入排序的一种,又称缩小增量排序,是插入排序算法的一种更高效的改进版本。

前面学习插入排序的时候,我们会发现一个很不友好的事儿,如果已排序的分组元素为{2,5,7,9,10},未排序的分组

元素为{1,8},那么下一个待插入元素为1,我们需要拿着1从后往前,依次和10,9,7,5,2进行交换位置,才能完成真

正的插入,每次交换只能和相邻的元素交换位置。那如果我们要提高效率,直观的想法就是一次交换,能把1放到

更前面的位置,比如一次交换就能把1插到25之间,这样一次交换1就向前走了5个位置,可以减少交换的次数,

这样的需求如何实现呢?接下来我们来看看希尔排序的原理。

需求:

排序前:{9,1,2,5,7,4,8,6,3,5}

排序后:{1,2,3,4,5,5,6,7,8,9}

排序原理:

1.

选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组;

2.

对分好组的每一组数据完成插入排序;

3.

减小增长量,最小减为1,重复第二步操作。

 

增长量h的确定:增长量h的值每一固定的规则,我们这里采用以下规则:

 

1. import java.util.Arrays;
2. 
3. public class Shell {
4. public static void sort(Comparable[] a){
5. int N=a.length;
6. int h=1;
7. while(h<N/2){
8.             h=2*h+1;
9.         }
10. while (h>=1){
11. for(int i=h;i<N;i++){
12. for(int j=i;j>=h;j-=h){
13. if(greater(a[j-h],a[j])){
14.                         exch(a,j,j-h);
15.                     }else {
16. break;
17.                     }
18.                 }
19.             }
20.         h/=2;
21.         }
22.     }
23. private static boolean greater(Comparable v,Comparable w){
24. return v.compareTo(w)>0;
25.     }
26. public static void exch(Comparable[] a,int i,int j){
27.         Comparable t=a[i];
28.         a[i]=a[j];
29.         a[j]=t;
30. 
31.     }
32. 
33. }
34. class Test4{
35. public static void main(String[] args) {
36.       Integer[] a={45,52,23,48,7543,3};
37.       Shell.sort(a);
38.          System.out.println(Arrays.toString(a));
39. 
40. 
41.      }
42. }
43. 
44.

希尔排序的时间复杂度分析

在希尔排序中,增长量h并没有固定的规则,有很多论文研究了各种不同的递增序列,但都无法证明某个序列是最

好的,对于希尔排序的时间复杂度分析,已经超出了我们课程设计的范畴,所以在这里就不做分析了。

我们可以使用事后分析法对希尔排序和插入排序做性能比较。

在资料的测试数据文件夹下有一个reverse_shell_insertion.txt文件,里面存放的是从1000001的逆向数据,我们

可以根据这个批量数据完成测试。测试的思想:在执行排序前前记录一个时间,在排序完成后记录一个时间,两个

时间的时间差就是排序的耗时。

希尔排序和插入排序性能比较测试代码:

1. import java.io.BufferedReader;
2. import java.io.FileInputStream;
3. import java.io.InputStreamReader;
4. import java.util.ArrayList;
5. import java.util.Arrays;
6. 
7. public class SortCompare {
8. public static void main(String[] args)throws Exception {
9.         ArrayList<Integer>list=new ArrayList<>();
10.         BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("reverse_shell_insertion.txt")));
11.         String line=null;
12. while((line=reader.readLine())!=null){
13.             list.add(Integer.valueOf(line));}
14. reader.close();
15. Integer[] arr=new Integer[list.size()];
16. list.toArray(arr);
17. testInsertion(arr);
18. testShell(arr);
19. 
20.     }
21. 
22. public static void testShell(Integer[] arr){
23. long start=System.currentTimeMillis();
24.         Shell.sort(arr);
25. long end=System.currentTimeMillis();
26.         System.out.println("使用希尔排序耗时:"+(end-start));
27.     }
28. 
29. public static void testInsertion(Integer[] arr){
30. long start=System.currentTimeMillis();
31.         Insertion.sort(arr);
32. long end=System.currentTimeMillis();
33.     System.out.println("使用插入排序耗时:"+(end-start));
34. }
35. 
36. }

2.2.2 归并排序

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子

序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序

表,称为二路归并。

需求:

排序前:{8,4,5,7,1,3,6,2}

排序后:{1,2,3,4,5,6,7,8}

排序原理:

1.尽可能的一组数据拆分成两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子组的元素个数是

1为止。

2.

将相邻的两个子组进行合并成一个有序的大组;

3.不断的重复步骤2,直到最终只有一个组为止。

 

1. import java.io.BufferedInputStream;
2. import java.util.*;
3. public class Main{
4. private static int N=100010;
5. private static int[] a=new int[N];
6. private static int[] t=new int[N];
7. public static void main(String[] args) {
8. Scanner sc=new Scanner(new BufferedInputStream(System.in));
9. int n= sc.nextInt();
10. for(int i=0;i<n;i++){
11.     a[i]= sc.nextInt();
12. }
13. int l=0,r=n-1;
14.         mergeSort(a,l,r);
15. for(int i=0;i<n;i++){
16.             System.out.print(a[i]);
17. if(i!=n-1) System.out.print(" ");
18.         }
19.     }
20. public static void mergeSort(int[] a,int l,int r){
21. if(l>=r){
22. return;
23.   }
24. int m=l+r>>1;
25.   mergeSort(a,l,m);
26.   mergeSort(a,m+1,r);
27. int i=l,j=m+1,k=0;
28. while(i<=m&&j<=r){
29.   t[k++]=a[i]<a[j]?a[i++]:a[j++];
30.   }
31. while(i<=m){
32.      t[k++]=a[i++];
33.  }
34. while(j<=r){
35.       t[k++]=a[j++];
36.   }
37. for( i=l,k=0;i<=r;i++,k++){
38.      a[i]=t[k];
39.  }
40. 
41. }
42. 
43. }
44. 
45. 
46. 
47. 
48. 
49.

2.3 快速排序

快速排序是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一

部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序

过程可以递归进行,以此达到整个数据变成有序序列。

需求:

排序前:{6, 1, 2, 7, 9, 3, 4, 5, 8}

排序后:{1, 2, 3, 4, 5, 6, 7, 8, 9}

排序原理:

1.首先设定一个分界值,通过该分界值将数组分成左右两部分;

2.将大于或等于分界值的数据放到到数组右边,小于分界值的数据放到数组的左边。此时左边部分中各元素都小于

或等于分界值,而右边部分中各元素都大于或等于分界值;

3.然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两

部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。

4.重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当

左侧和右侧两个部分的数据排完序后,整个数组的排序也就完成了。

 

切分原理:

把一个数组切分成两个子数组的基本思想:

1.找一个基准值,用两个指针分别指向数组的头部和尾部;

2.先从尾部向头部开始搜索一个比基准值小的元素,搜索到即停止,并记录指针的位置;

3.再从头部向尾部开始搜索一个比基准值大的元素,搜索到即停止,并记录指针的位置;

4.交换当前左边指针位置和右边指针位置的元素;

5.重复2,3,4步骤,直到左边指针的值大于右边指针的值停止。

1. import java.util.Scanner;
2. import java.io.BufferedInputStream;
3. public class Main{
4. 
5. 
6. public static void main(String[] args) {
7.         Scanner sc=new Scanner(new BufferedInputStream(System.in));
8. int n=sc.nextInt();
9. int[] a=new int[n];
10. for(int i=0;i<n;i++){
11.             a[i]= sc.nextInt();
12.         }
13.     quickSort(a,0,n-1);
14. for(int i=0;i<n;i++){
15.           System.out.print(a[i]);
16. if(i!=n-1) System.out.print(" ");
17.       }
18. 
19.     }
20. private static void quickSort(int[] a,int left,int right){
21. if(left>=right)return;
22. int x=a[(left+right)/2],i=left-1,j=right+1;
23. while(i<j){
24. do{
25.         i++;
26.     }while(a[i]<x);
27. do{
28.     j--;
29. }while(a[j]>x);
30. if(i<j){
31. int temp=a[i];
32.  a[i]=a[j];
33.  a[j]=temp;
34. }
35. }
36. quickSort(a,left,j);
37. quickSort(a,j+1,right);
38. 
39.    }
40. 
41. 
42. }

快速排序和归并排序的区别:

快速排序是另外一种分治的排序算法,它将一个数组分成两个子数组,将两部分独立的排序。快速排序和归并排序

是互补的:归并排序将数组分成两个子数组分别排序,并将有序的子数组归并从而将整个数组排序,而快速排序的

方式则是当两个数组都有序时,整个数组自然就有序了。在归并排序中,一个数组被等分为两半,归并调用发生在

处理整个数组之前,在快速排序中,切分数组的位置取决于数组的内容,递归调用发生在处理整个数组之后。

快速排序时间复杂度分析:

快速排序的一次切分从两头开始交替搜索,直到leftright重合,因此,一次切分算法的时间复杂度为O(n),但整个

快速排序的时间复杂度和切分的次数相关。

最优情况:每一次切分选择的基准数字刚好将当前序列等分。

 

如果我们把数组的切分看做是一个树,那么上图就是它的最优情况的图示,共切分了logn次,所以,最优情况下快

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

最坏情况:每一次切分选择的基准数字是当前序列中最大数或者最小数,这使得每次切分都会有一个子组,那么总

共就得切分n次,所以,最坏情况下,快速排序的时间复杂度为O(n^2);

 

平均情况:每一次切分选择的基准数字不是最大值和最小值,也不是中值,这种情况我们也可以用数学归纳法证

明,快速排序的时间复杂度为O(nlogn),由于数学归纳法有很多数学相关的知识,容易使我们混乱,所以这里就不对

平均情况的时间复杂度做证明了。

2.4 排序的稳定性

稳定性的定义:

数组arr中有若干元素,其中A元素和B元素相等,并且A元素在B元素前面,如果使用某种排序算法排序后,能够保

A元素依然在B元素的前面,可以说这个该算法是稳定的。

 

稳定性的意义:

如果一组数据只需要一次排序,则稳定性一般是没有意义的,如果一组数据需要多次排序,稳定性是有意义的。例

如要排序的内容是一组商品对象,第一次排序按照价格由低到高排序,第二次排序按照销量由高到低排序,如果第

二次排序使用稳定性算法,就可以使得相同销量的对象依旧保持着价格高低的顺序展现,只有销量不同的对象才需

要重新排序。这样既可以保持第一次排序的原有意义,而且可以减少系统开销。

第一次按照价格从低到高排序:

 

常见排序算法的稳定性:

冒泡排序:

只有当arr[i]>arr[i+1]的时候,才会交换元素的位置,而相等的时候并不交换位置,所以冒泡排序是一种稳定排序

算法。

选择排序:

选择排序是给每个位置选择当前元素最小的,例如有数据{5(1)8 5(2)29 },第一遍选择到的最小元素为2

所以5(1)会和2进行交换位置,此时5(1)到了5(2)后面,破坏了稳定性,所以选择排序是一种不稳定的排序算法。

插入排序:

比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其

后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么把要插入的元素放在相等

元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序

是稳定的。

希尔排序:

希尔排序是按照不同步长对元素进行插入排序,虽然一次插入排序是稳定的,不会改变相同元素的相对顺序,但在

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

稳定的。

归并排序:

归并排序在归并的过程中,只有arr[i]<arr[i+1]的时候才会交换位置,如果两个元素相等则不会交换位置,所以它

并不会破坏稳定性,归并排序是稳定的。

快速排序:

快速排序需要一个基准值,在基准值的右侧找一个比基准值小的元素,在基准值的左侧找一个比基准值大的元素,

然后交换这两个元素,此时会破坏稳定性,所以快速排序是一种不稳定的算法。

一,对数组进行排序:

通常情况下我们可以使用Array.sort()来对数组进行排序,有以下3种情况:

1.Array.sort(int[] a)

直接对数组进行升序排序

2.Array.sort(int[] a , int fromIndex, int toIndex)

对数组的从fromIndex到toIndex进行升序排序,注意这是左闭右开的

3.新建一个comparator从而实现自定义比较

1. import java.util.*;
2. public class no {
3. public static void main(String []args)
4.     {
5. int[] ints=new int[]{2,324,4,57,1};
6. 
7.         System.out.println("增序排序后顺序");
8.         Arrays.sort(ints);
9. for (int i=0;i<ints.length;i++)
10.         {
11.             System.out.print(ints[i]+" ");
12.         }
13. 
14. 
15.         System.out.println("\n减序排序后顺序");
16. //要实现减序排序,得通过包装类型数组,基本类型数组是不行滴
17. //倒过来是大顶堆
18.         Integer[] integers=new Integer[]{2,324,4,4,6,1};
19.         Arrays.sort(integers, new Comparator<Integer>()
20.         {
21.             @Override
22. public int compare(Integer o1, Integer o2)
23.             {
24. return o2-o1;
25.             }
26. 
27. 
28. public boolean equals(Object obj)
29.             {
30. return false;
31.             }
32.         });
33. for (Integer integer:integers)
34.         {
35.             System.out.print(integer+" ");
36.         }
37. 
38. 
39. 
40.         System.out.println("\n对部分排序后顺序");
41. int[] ints2=new int[]{212,43,2,324,4,4,57,1};
42. //对数组的[2,6)位进行排序
43. 
44.         Arrays.sort(ints2,2,6);
45. for (int i=0;i<ints2.length;i++)
46.         {
47.             System.out.print(ints2[i]+" ");
48.         }
49. 
50.     }
51. }

二,对自定义类进行排序

当我们处理自定义类型的排序时,一般将自定义类放在List种,之后再进行排序

一般我们对自定义类型数据进行重写Comparator来进行对数据进行比较

具体方法如下:

1. public static class Adam
2. {
3. int ID ;
4. int val ;
5. String name ;
6.     Adam(int ID , String name , int val)
7.     {
8. this.ID = ID ;
9. this.name = name ;
10. this.val = val ;
11.       }
12. }
13. Collections.sort(list, new Comparator<Object>(){      //我们希望对自定义Adam中的ID进行排序
14.     public int compare(Object a , Object b)
15.     {
16.         Adam student1 = (Adam)a ;
17.         Adam student2 = (Adam)b ;
18. return student1.ID - student2.ID ;
19.     }
20. });
21.

Arrays.sort(int[])都是基于比较的排序的示例,因此必须具有最坏情况的复杂度Ω(n log n)

三. Arrays.fill()

用法1:接受2个参数

Arrays.fill( a1, value );

注:a1是一个数组变量,value是一个a1中元素数据类型的值,作用:填充a1数组中的每个元素都是value

例如:

boolean[] a1 = new boolean[5];

Arrays.fill( a1,true );

结果 a1[] = {true,true,true,true,true};

用法2:接受4个参数

例如:

String[] a9 = new String[6];

Arrays.fill(a9, “Hello”);

Arrays.fill(a9, 3, 5,“World”);

结果是 a9[] = {Hello,Hello,Hello,World,World,Hello};

第一个参数指操作的数组,第二个和第三个指在该数组的某个区域插入第四个参数,第二个参数指起始元素下标(包含该下标),第三个参数指结束下标(不包含该下标),注意:java的数组下标从0开始

相关文章
|
4月前
|
算法
【十大排序】深入浅出冒泡排序
【十大排序】深入浅出冒泡排序
|
4月前
|
存储 算法
【408数据结构与算法】—排序(十四)
【408数据结构与算法】—排序(十四)
|
6月前
|
搜索推荐 算法 Shell
【数据结构】排序合集(万字详解)
【数据结构】排序合集(万字详解)
|
6月前
|
存储 机器学习/深度学习 算法
数据结构与算法之二 排序
数据结构与算法之二 排序
22 0
|
6月前
|
存储 搜索推荐 算法
数据结构与算法之三 深入学习排序
数据结构与算法之三 深入学习排序
26 0
|
6月前
|
算法 搜索推荐
带你读《图解算法小抄》十四、排序(4)
带你读《图解算法小抄》十四、排序(4)
|
6月前
|
算法
带你读《图解算法小抄》十四、排序(13)
带你读《图解算法小抄》十四、排序(13)
|
6月前
|
算法 搜索推荐
带你读《图解算法小抄》十四、排序(1)
带你读《图解算法小抄》十四、排序(1)
|
6月前
|
算法
带你读《图解算法小抄》十四、排序(14)
带你读《图解算法小抄》十四、排序(14)
|
11月前
|
机器学习/深度学习 存储 搜索推荐
数据结构与算法-八大排序
对于排序的了解一定要理解思想,能够很清楚它的时间复杂度和空间复杂度,稳定性等特性。 稳定的排序有:直接插入排序、冒泡排序、归并排序 不稳定的排序有:希尔排序、选择排序、堆排序、快速排序、计数排序
数据结构与算法-八大排序

热门文章

最新文章