快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
Note:参考百度百科 http://baike.baidu.com/view/19016.htm
快速排序,理论上最快的排序算法之一。简单的说就是先找一个值(pivot,中文可能解释“枢”),然后将数组分成两个部分(Partition),大于这个值的,和小于这个值的,再重复上面的步骤,直到完成排序。那我们就先看看分组(Partition)是怎么做的。
public class Partitioning { public static int[] theArray; public static int arraySize; public Partitioning(int arraySize) { System.out.println("Create a randan array"); this.arraySize = arraySize; theArray = new int[arraySize]; generateRandomArray(); } public void partitionArray(int pivot) { int leftPoint = -1; int rightPoint = arraySize; while (true) { while (leftPoint < arraySize && theArray[++leftPoint] < pivot) ; while (rightPoint > 0 && theArray[--rightPoint] > pivot) ; if (leftPoint >= rightPoint) break; else swapValues(leftPoint, rightPoint); } } public static void main(String[] args) { Partitioning p = new Partitioning(10); p.printArray(); System.out.println(); System.out.println("Partition array by pivot 30"); p.partitionArray(30); p.printArray(); } public void printArray() { StringBuffer sb = new StringBuffer("-"); for (int i = 0; i<arraySize; i++){ sb.append("-----"); } String septalLine= sb.toString(); System.out.println(septalLine); for (int i = 0; i<arraySize; i++){ if (i/10 == 0) System.out.print("| " + i + " "); else System.out.print("| " + i + " "); } System.out.println("|"); System.out.println(septalLine); for (int i = 0; i<arraySize; i++){ System.out.print("| " + theArray[i] + " "); } System.out.println("|"); System.out.println(septalLine); } public void swapValues(int indexOne, int indexTwo) { int temp = theArray[indexOne]; theArray[indexOne] = theArray[indexTwo]; theArray[indexTwo] = temp; ; } public void generateRandomArray() { for (int i = 0; i < arraySize; i++) { theArray[i] = (int) (Math.random() * 40 + 10); } } }
最关键的代码
public void partitionArray(int pivot) { //设两个指针,分别指向数组的最左面和最有面 int leftPoint = -1; int rightPoint = arraySize; while (true) { //左指针,从左往右扫描,找到大于pivot的值 while (leftPoint < arraySize && theArray[++leftPoint] < pivot) ; //右指针,从右往左扫描,找到小于pivot的值 while (rightPoint > 0 && theArray[--rightPoint] > pivot) ; // 退出条件 if (leftPoint >= rightPoint) break; else // 交换左右指针的值 swapValues(leftPoint, rightPoint); } }
看看结果数组被分成两个部分,数组被分成了两个部分,小于30的 0~4, 和大于30的5~9
输出结果
Create a randan array --------------------------------------------------- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | --------------------------------------------------- | 48 | 20 | 36 | 23 | 27 | 10 | 43 | 49 | 26 | 39 | --------------------------------------------------- Partition array by pivot 30 --------------------------------------------------- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | --------------------------------------------------- | 26 | 20 | 10 | 23 | 27 | 36 | 43 | 49 | 48 | 39 | ---------------------------------------------------
如果,你看懂的分组(Partition)的代码,那么快速排序就简单了。就是用低轨(Recursion)将分好的数组反复的做分组,直到完成排序。
看代码:
public class QuickSort { private int [] anArray; private int arraySize; public QuickSort(int arraySize){ this.arraySize = arraySize; anArray = new int[arraySize]; generateRandomArray(); } public void generateRandomArray(){ for (int i=0; i<arraySize; i++){ anArray[i] = (int)(Math.random()*50 + 10); } } public void printArray() { StringBuffer sb = new StringBuffer("-"); for (int i = 0; i<arraySize; i++){ sb.append("-----"); } String septalLine= sb.toString(); System.out.println(septalLine); for (int i = 0; i<arraySize; i++){ if (i/10 == 0) System.out.print("| " + i + " "); else System.out.print("| " + i + " "); } System.out.println("|"); System.out.println(septalLine); for (int i = 0; i<arraySize; i++){ System.out.print("| " + anArray[i] + " "); } System.out.println("|"); System.out.println(septalLine); } public void quickSort(int left, int right){ if(right - left <=0) return ; else { int pivot = anArray[right]; int partitionLocation = partitionArray(left, right, pivot); quickSort(left, partitionLocation -1); quickSort(partitionLocation+1, right); } } public int partitionArray(int left, int right, int pivot){ int leftPoint = left -1; int rightPoint = right; while (true) { while ( anArray[++leftPoint] < pivot) ; while (rightPoint > 0 && anArray[--rightPoint] > pivot) ; if (leftPoint >= rightPoint) break; else swapValues(leftPoint, rightPoint); } swapValues (leftPoint, right); return leftPoint; } public void swapValues(int indexOne, int indexTwo) { int temp = anArray[indexOne]; anArray[indexOne] = anArray[indexTwo]; anArray[indexTwo] = temp; ; } public static void main(String[] args) { System.out.println("Create a Randan Array:"); QuickSort qs = new QuickSort(20); qs.printArray(); System.out.println(); System.out.println("Sort the array by Quick Sort algorithem"); qs.quickSort(0, qs.arraySize-1); qs.printArray(); } }
输出结果
Create a Randan Array: ----------------------------------------------------------------------------------------------------- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ----------------------------------------------------------------------------------------------------- | 40 | 18 | 51 | 59 | 39 | 25 | 42 | 43 | 35 | 54 | 59 | 16 | 31 | 26 | 10 | 24 | 18 | 53 | 24 | 35 | ----------------------------------------------------------------------------------------------------- Sort the array by Quick Sort algorithem ----------------------------------------------------------------------------------------------------- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ----------------------------------------------------------------------------------------------------- | 10 | 16 | 18 | 18 | 24 | 24 | 25 | 26 | 31 | 35 | 35 | 39 | 40 | 42 | 43 | 51 | 53 | 54 | 59 | 59 | -----------------------------------------------------------------------------------------------------
本文出自 “10314466” 博客,请务必保留此出处http://10324466.blog.51cto.com/10314466/1670750
原文地址:http://10324466.blog.51cto.com/10314466/1670750