最近看了一下快速排序的算法,写出来和大家一起分享一下吧。
快速排序法(QuickSort)是一种非常快的对比排序方法。它也Divide-And-Conquer思想的实现之一。自从其产生以来,快速排序理论得到了极大的改进,然而在实际中却十分难以编程出正确健壮的代码。本文将对快速排序算法的基本理论和编程实践方面做作一个全面的讲解。在本文讲解中,将忽略很多细枝末节,试图给读者形成一个非常具体的快速排序形象。
1.快速排序---基本理论
因为该算法是Divide-And-Conquer思想的一个实现,所以本文将以Divide-And-Conquer思想对其进行分析。首先,假设所要排序的数字存储在数组S中,则该算法的操作可以拆分为两部分:
在S中选出一个元素v;
将S数组分为三个子数组。其中v这个元素单独形成子数组1,比v小的元素形成子数组2,比v大的元素形成自数组3.
分别对子数组2和子数组3进行前两步操作,实现递归排序;
返回时,依次返回S1,V,S2;
下面给出一个简单的排序实例对以上算法进行简单说明:
1.初始数组为--------------> S: 5,10,13,8,3
2.将第一个元素赋值给v----->v = 5;
3.以v为标准将S进行拆分--->[3],[5],[10,13,8] <----------将得到的数组命名为S1, S2;
重复上面的1 2 3 过程,直到数组不能再细分:
对子数组S1进行拆分->[ ], [3], [ ] <--------------------拆分之后,第一个子数组为空。将得到的数组命名为S12;
对子数组S2进行拆分-----> [8],[10], [13]<---------------将得到的数组命名为S22;
。。。。
最后得到的数组为-------->3,5,8,10,13;
快速排序法(QuickSort)是一种非常快的对比排序方法。它也Divide-And-Conquer思想的实现之一。自从其产生以来,快速排序理论得到了极大的改进,然而在实际中却十分难以编程出正确健壮的代码。本文将对快速排序算法的基本理论和编程实践方面做作一个全面的讲解。在本文讲解中,将忽略很多细枝末节,试图给读者形成一个非常具体的快速排序形象。
1.快速排序---基本理论
因为该算法是Divide-And-Conquer思想的一个实现,所以本文将以Divide-And-Conquer思想对其进行分析。首先,假设所要排序的数字存储在数组S中,则该算法的操作可以拆分为两部分:
在S中选出一个元素v;
将S数组分为三个子数组。其中v这个元素单独形成子数组1,比v小的元素形成子数组2,比v大的元素形成自数组3.
分别对子数组2和子数组3进行前两步操作,实现递归排序;
返回时,依次返回S1,V,S2;
下面给出一个简单的排序实例对以上算法进行简单说明:
1.初始数组为--------------> S: 5,10,13,8,3
2.将第一个元素赋值给v----->v = 5;
3.以v为标准将S进行拆分--->[3],[5],[10,13,8] <----------将得到的数组命名为S1, S2;
重复上面的1 2 3 过程,直到数组不能再细分:
对子数组S1进行拆分->[ ], [3], [ ] <--------------------拆分之后,第一个子数组为空。将得到的数组命名为S12;
对子数组S2进行拆分-----> [8],[10], [13]<---------------将得到的数组命名为S22;
。。。。
最后得到的数组为-------->3,5,8,10,13;
这里找了一个gif图
根据以上分析,编写快速排序算法程序,得到的程序如下:
package sort;
public class qSort {
public static void main(String[] args) {
double array[] = {12.0, 32.0, 3.0, 2.0, 54.0, 23.0, 43.0, 76.0, 44.0, 54.0, 43.0, 13.0};
sortArray(array, 0, array.length);
print(array);
}
public static void print(double array[]) {
for(int i=0; i<array.length; i++){
System.out.print(array[i] + " ");
}
}
private static int partition(double[] array,int start, int end) {
double temp;
double key = array[start];
int i = start;
for(int j = i + 1 ; j< end ; j++){
if(array[j] < key){
i++;
temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
temp = array[start];
array[start] = array[i];
array[i] = temp;
return i;
}
private static void sortArray(double[] array, int start, int end) {
if(start < end){
int i = partition(array, start, end);
sortArray(array, start, i);
sortArray(array, i+1, end);
}
}
}
可以对上面的算法进行优化:
在构建:“比v小的元素形成子数组2,比v大的元素形成自数组3”时,可以从数组的两边”同时(并不是真正意义上的同时)“查找,以提高排序效率。
当然优化的办法还有别的,比如 v 值的选取,选择一个合适的 v 值,也能提高算法的效率。
由于比较简单,这里就直接贴代码了.
private static void partitionSort(double[] array,int start, int end) {
if(start >= end){
return ;
}
double temp;
double key = array[start];
int i = start, j = end-1;
while(i < j){
while (array[j] > key && j > i) {
j--;
}
while (array[i] <= key && i < j) {
i++;
}
if(i < j){
temp = array[i];
array[i] = array[j];
array[j] = temp;
}else {
temp = array[start];
array[start] = array[i];
array[i] = temp;
}
}
partitionSort(array, start, i);
partitionSort(array, i+1, end);
}