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-062 * 功能:冒泡排序法演示3 */
4 packagetest;5 import java.util.*;6 public classDemo1 {7
8 public static voidmain(String[] args) {9 //TODO Auto-generated method stub
10
11 int arr1[]={27,23,12,33,76,55};12 Bubble bubble=newBubble();13 bubble.sort(arr1);14 //打印排序后的结果
15 for(int i=0;i
21
22 int len=60000;23 int arr[]=new int[len];24 for(int i=0;i
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 classBubble42 {43 //排序方法,注意sort前为void,它与进行数值处理的函数不同,无返回值
44 public void sort(intarr[])45 {46 //用于交换的临时变量
47 int temp=0;48 //外层循环,决定一共走几趟
49 for(int i=0;i
52 for(int j=0;j",反之,为"
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 Hoare在1962年提出。 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
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-062 * 功能:选择排序法演示3 */
4 packagetest;5 import java.util.*;6 public classDemo2 {7
8 public static voidmain(String[] args) {9 //TODO Auto-generated method stub
10
11 int arr1[]={27,23,12,33,76,55};12 Select select=newSelect();13 select.sort(arr1);14 //打印排序后的结果
15 for(int i=0;i
21
22 int len=60000;23 int arr[]=new int[len];24 for(int i=0;i
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 classSelect41 {42 public void sort(intarr[])43 {44 int temp=0;45 for(int i=0;i
48 int min=arr[i];49 int minIndex=i;50 for(int j=i+1;j",反之,为"
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的六个排序码分别为:17,3,25,14,20,9。它的直接插入排序的执行过程如图9所示。
演示代码如下:
1 /**日期:2016-03-062 * 功能:插入排序法演示3 */
4 packagetest;5
6 importjava.util.Calendar;7
8 public classDemo3 {9
10 public static voidmain(String[] args) {11 //TODO Auto-generated method stub
12
13 int arr1[]={27,23,12,33,76,55};14 Insert Insert=newInsert();15 Insert.sort(arr1);16 //打印排序后的结果
17 for(int i=0;i
23
24 int len=60000;25 int arr[]=new int[len];26 for(int i=0;i
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 classInsert43 {44 public void sort(intarr[])45 {46 for(int i=1;i
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 排序方法比较及总结
排序速度:冒泡排序法
面试常考:冒泡排序法、选择排序法、插入排序法
快速排序法:理解较困难,可记忆。