17.1 排序介绍

排序是将一群数据,依指定的顺序进行排列的过程。

排序(Sorting)是数据处理中一种很重要的运算,同时也是很常用的运算,一般数据处理工作25%的时间都在进行排序。简单地说,排序就是把一组记录(元素)按照某个域的值的递增(即由小到大)或递减(即由大到小)的次序重新排序的过程。

17.2 排序分类

1、内部排序:

指将需要处理的所有数据都加载到内部存储器中进行排序。

包括:交换式排序法、选择式排序法、插入式排序法。

2、外部排序法:

数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。

包括:合并排序法、直接合并排序法。

17.3 内部排序

17.3.1 交换式排序法

交换式排序法属于内部排序法,是运用数据值比较后,依判断规则对数据位置进行交换,以达到排序的目的。

交换式排序法又分为两种:

1、冒泡排序法(Bubble sort

2、快速排序法(Quick sort

17.3.1.1 冒泡排序法

冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的排序码,或发现逆序则交换,使排序码较小的元素逐渐从后部向前部(从下标较大的单元移向下标较小的单元),就像水底下的气泡一样逐渐向上冒。

因为排序的过程中,个元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换,从而减少不必要的比较。

演示代码如下:

 

 1 /**日期:2016-03-06
 2  * 功能:冒泡排序法演示
 3  */
 4 package test;
 5 import java.util.*;
 6 public class Demo1 {
 7 
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10         
11         int arr1[]={27,23,12,33,76,55};
12         Bubble bubble=new Bubble();
13         bubble.sort(arr1);
14         //打印排序后的结果
15         for(int i=0;i<arr1.length;i++)
16         {
17             System.out.print(arr1[i]+" ");
18         }
19         System.out.println("");
20         
21 
22         int len=60000;
23         int arr[]=new int[len];
24         for(int i=0;i<arr.length;i++)
25         {
26             //Math.random()可以生成0~1,不包括1,之间的数
27             arr[i]=(int)(Math.random()*10000);
28         }
29         
30         Calendar cal=Calendar.getInstance();
31         System.out.println("冒泡排序法排序前时间:"+cal.getTime());
32         bubble.sort(arr);
33         cal=Calendar.getInstance(); //注意cal要重写一遍
34         System.out.println("冒泡排序法排序后时间:"+cal.getTime());    
35     
36     }
37 
38 }
39 
40 //冒泡排序法
41 class Bubble
42 {
43     //排序方法,注意sort前为void,它与进行数值处理的函数不同,无返回值
44     public void sort(int arr[])
45     {
46         //用于交换的临时变量
47         int temp=0;
48         //外层循环,决定一共走几趟
49         for(int i=0;i<(arr.length-1);i++)
50         {
51             //内存循环,开始逐个比较,如果发现前一个元素比后一个大,则两者交换
52             for(int j=0;j<(arr.length-1-i);j++)
53             {
54                 //从小到大排序为">",反之,为"<"
55                 if(arr[j]>arr[j+1])
56                 {
57                     //换位
58                     temp=arr[j];
59                     arr[j]=arr[j+1];
60                     arr[j+1]=temp;
61                 }
62             }
63         }
64     }
65 }
View Code

 

运行结果如下:

 

1 12 23 27 33 55 76 
2 冒泡排序法排序前时间:Sun Mar 06 22:41:30 CST 2016
3 冒泡排序法排序后时间:Sun Mar 06 22:41:35 CST 2016
View Code

 

 

 

 

17.3.1.1 快速排序法

快速排序法(Quicksort)是对冒泡排序的一种改进。由C.A.R Hoare1962年提出。 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

 

17.3.2 选择式排序法

选择式排序也属于内部排序法,是从欲排序的数组中,按指定的规则选出某一元素,经过和其他元素重整,再依原则交换后达到排序的目的。

选择式排序又可分为两种:

1、选择排序法(Selectiong Sort

2、堆排序法(Heap Sort

17.3.2.1 选择排序法

选择排序(select sorting)也是一种简单的排序方法。它的基本思想是:第一次从R[0]-R[n-1]中选择最小值,与R[0]交换;第二次从R[1]-R[n-1]中选择最小值,与R[1]交换;第三次从R[2]-R[n-1]中选择最小值,与R[2]交换......i次从R[i-1]-R[n-1]中选择最小值,与R[i-1]交换......n-1次从R[n-2]-R[n-1]中选择最小值,与R[n-2]交换。总共通过n-1次,得到一个按排序码从小到大排列的有序序列。

 

演示代码如下:

 1 /**日期:2016-03-06
 2  * 功能:选择排序法演示
 3  */
 4 package test;
 5 import java.util.*;
 6 public class Demo2 {
 7 
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10         
11         int arr1[]={27,23,12,33,76,55};
12         Select select=new Select();
13         select.sort(arr1);        
14         //打印排序后的结果
15         for(int i=0;i<arr1.length;i++)
16         {
17             System.out.print(arr1[i]+" ");
18         }
19         System.out.println("");
20         
21         
22         int len=60000;
23         int arr[]=new int[len];
24         for(int i=0;i<arr.length;i++)
25         {
26             //Math.random()可以生成0~1,不包括1,之间的数
27             arr[i]=(int)(Math.random()*10000);
28         }
29         
30         Calendar cal=Calendar.getInstance();
31         System.out.println("选择排序法排序前时间:"+cal.getTime());
32         select.sort(arr);
33         cal=Calendar.getInstance(); //注意cal要重写一遍
34         System.out.println("选择排序法排序后时间:"+cal.getTime());        
35     }
36 
37 }
38 
39 //选择排序法
40 class Select
41 {
42     public void sort(int arr[])
43     {
44         int temp=0;
45         for(int i=0;i<(arr.length-1);i++)
46         {
47             //找出arr[i]及之后的所有数中的最小值,首先假定最小值为arr[i]
48             int min=arr[i];
49             int minIndex=i;
50             for(int j=i+1;j<(arr.length);j++)
51             {
52                 //从小到大排序为">",反之,为"<"
53                 if(min>arr[j])
54                 {
55                     min=arr[j];
56                     minIndex=j;
57                 }
58             }
59             //将最小值与arr[i]交换位置,如果自己就是最小值,自己与自己交换
60             temp=arr[i];
61             arr[i]=arr[minIndex];
62             arr[minIndex]=temp;
63         }
64     }
65 }
View Code

 

运行结果如下:

1 12 23 27 33 55 76 
2 选择排序法排序前时间:Sun Mar 06 22:46:47 CST 2016
3 选择排序法排序后时间:Sun Mar 06 22:46:48 CST 2016
View Code

 

17.3.2.2 堆排序法

 

 

17.3.3 插入式排序法

插入式排序法属于内部排序法,是对于欲排序的元素以插入的方式找寻元素的适当位置,以达到排序的目的。

插入式排序法又可分为3种:

1、插入排序法(Insertion sort

2、谢耳排序法(shell sort

3、二叉树排序法(Binary-tree sort

17.3.3.1 插入排序法

插入排序的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它加入到有序表中的适当位置,使之成为新的有序表。

例如 n=6,数组R的六个排序码分别为:1732514209。它的直接插入排序的执行过程如图9所示。

 

演示代码如下:

 1 /**日期:2016-03-06
 2  * 功能:插入排序法演示
 3  */
 4 package test;
 5 
 6 import java.util.Calendar;
 7 
 8 public class Demo3 {
 9 
10     public static void main(String[] args) {
11         // TODO Auto-generated method stub
12         
13         int arr1[]={27,23,12,33,76,55};
14         Insert Insert=new Insert();
15         Insert.sort(arr1);        
16         //打印排序后的结果
17         for(int i=0;i<arr1.length;i++)
18         {
19             System.out.print(arr1[i]+" ");
20         }
21         System.out.println("");
22         
23         
24         int len=60000;
25         int arr[]=new int[len];
26         for(int i=0;i<arr.length;i++)
27         {
28             //Math.random()可以生成0~1,不包括1,之间的数
29             arr[i]=(int)(Math.random()*10000);
30         }
31         
32         Calendar cal=Calendar.getInstance();
33         System.out.println("插入排序法排序前时间:"+cal.getTime());
34         Insert.sort(arr);
35         cal=Calendar.getInstance(); //注意cal要重写一遍
36         System.out.println("插入排序法排序后时间:"+cal.getTime());    
37     }
38 
39 }
40 
41 //插入排序法
42 class Insert
43 {
44     public void sort(int arr[])
45     {
46         for(int i=1;i<arr.length;i++)
47         {
48             //带插入的值
49             int insertVal=arr[i];
50             //首先index指向待插入的值的前一位数
51             int index=i-1;
52             //从小到大排序为">",反之,为"<"
53             while(index>=0&&arr[index]>insertVal)
54             {
55                 arr[index+1]=arr[index];
56                 index--;
57             }
58             arr[index+1]=insertVal;
59         }
60     }
61 }
View Code

 

运行结果如下:

1 12 23 27 33 55 76 
2 插入排序法排序前时间:Sun Mar 06 22:48:09 CST 2016
3 插入排序法排序后时间:Sun Mar 06 22:48:10 CST 2016
View Code

 

17.3.3.2 谢耳排序法

 

17.3.3.3 二叉树排序法

17.4 外部排序

17.4.1 合并排序法

 

 

17.4.2 直接合并排序法

 

17.5 排序方法比较及总结

排序速度:冒泡排序法<选择排序法<插入排序法<快速排序法

面试常考:冒泡排序法、选择排序法、插入排序法

快速排序法:理解较困难,可记忆。