快速排序(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