快速排序的三种实现方法体会
2014-04-13 21:35
288 查看
快速排序有三种实现方法,网上也有不少人总结出来,但是其中或多或少都有些错误。在这里只是说一下我自己的心得和体会。
三种快速排序算法的区别其实就是分割操作的区别。说它有三种快速排序,也只是说它有三种分割操作而已。
分割操作:
将一个数组分为两部分,左半部分的数值都小于等于某一个数p,右半部分的数值都大于等于p。
第一种快速排序:大多数教科书里教给我们的方法,在前一文中已经说明。这里总结一下:
思想:
分割操作:选取数组中的第一个元素作为中位数p,此数将数组分为A[......., p ,........].数组的左半部分的数值都小于或等于p,数组的右半部分都大于或等于p。
然后对数组左右部分再进行递归的分割操作,直到整个数组完全有序为止。
分割操作步骤:
1. 选取A[low]作为中位数p,
2. 从数组的最右端往前找小于等于p的数: A[j]<=p; A[low]=A[j];
3. 再从数组的最左端往后找大小等于p的数:A[i]>=p; A[j]=A[i];
4. 再从数组的第j位置往前找小于等于p的数:A[j]<=p; A[i]=A[j]
5. 重复操作3,4.直到i==j为止。然后将A[i]=p;
分割结束。
例子:
{41, 24, 76, 11, 45, 64, 21, 69, 19, 11}
p=41;
{11, 24, 76, 11, 45, 64, 21, 69, 19, 11}
{11, 24, 76, 11, 45, 64, 21, 69, 19,76}
{11, 24,19, 11, 45, 64, 21, 69, 19, 76}
{11, 24, 19, 11, 45, 64, 21, 69, 45, 76}
{11, 24, 19, 11,21, 64, 21, 69, 45, 76}
{11, 24, 19, 11, 21, 64,64, 69, 45, 76}
{11, 24, 19, 11, 21, 41, 64, 69, 45, 76}
{11, 24, 19, 11, 21}{ 41}{ 64, 69, 45, 76}
分割结束。
第二种快速排序:
思想:
分割操作:选取p=A[(low+high)/2],作为中位数。将数组分割成A[........,...........]. 左半部分小于等于p,右半部分大于等于p,此时p的位置可能在左半部分中,也可能在右半部分中。
分别对数组的左半部分和右半部分递归进行分割操作,直至数组全部有序。
分割操作步骤:
1. 选取p=A[(low+high)/2]作为中位数
2. 从low往后找到一个大于p的数A[i],从high往前找到一个小于p的数A[j],swap(A[i],A[j]);
3. 直到low>=high为止,分割结束。
例子:
{41, 24, 76, 11, 45, 64, 21, 69, 19, 11}
p=45;
{41, 24, 76,11, 45, 64, 21, 69, 19,
11}
{41, 24, 11,11, 45, 64, 21, 69, 19,
76}
{41, 24, 11, 11,45, 64, 21, 69,
19, 76}
{41, 24, 11, 11, 19,64, 21, 69,
45, 76}
{41, 24, 11, 11,19,64, 21, 69, 45, 76}
{41, 24, 11, 11,19,21, 64, 69, 45, 76}
{41, 24, 11, 11,19,21} {
64, 69, 45, 76}
分割结束。
int Partion(int A[], int low, int high)
{
int middle=A[(low+high)/2];//注意这里不能写成middle=(low+high)/2;下面用A[middle].这样是错的!
//因为low和high值一直在变,所以A[middle]的值也一直在变。
while(1){
while(middle>A[low])low++;
while(middle<A[high])high--;
if(high<=low)
break;
int temp=A[high];
A[high]=A[low];
A[low]=temp;
high--;//如果没有这一步,则如果数组中有两相同的数,该程序会进入无限循环。
low++;
}
return high;//注意这里不能是renturn low;否则无线循环
}
void QuickSort2(int A[],int low,int high){
if(low<high){
int p=Partion(A,low,high);
QuickSort2(A,low,p);
QuickSort2(A,p+1,high);
}
}
第三种排序:
思想和第一种一样。不同就是分割方法。
分割思想:
P=A[high];作为中位数。
处理中的数组:
{{小于p},{大于p},{未处理},{p}}
处理结束后的数组:
{{小于p},{大于p},{p}}
{{小于p},{p},{大于p}}
I作为小于p分数组的最后一位下标,初试为-1;
J作为大于p的分数组的最后一位下标,也是处理中当前处理的元素下标。初始为0;末值为high。
遍历数组j=0;j<high; j++; if(A[j]<p) swap(A[++i],A[j]);
例子:
{41, 24, 76, 11, 45, 64, 21, 69, 19, 34}
P=34;
{41, 24, 76,11, 45, 64, 21, 69, 19, 34}
{24, 41, 76, 11, 45, 64, 21, 69, 19, 34}
{24, 41, 76, 11, 45, 64, 21, 69, 19,34}
{24, 11, 76, 41, 45, 64, 21, 69, 19, 34}
{24, 11, 76, 41, 45, 64, 21,69, 19, 34}
{24, 11, 21, 41, 45, 64, 76, 69, 19, 34}
{24, 11, 21, 41, 45, 64, 76, 69, 19,34}
{24, 11, 21, 19, 45, 64, 76, 69, 41, 34}
{24, 11, 21, 19, 45, 64, 76, 69, 41, 34}
{24, 11, 21, 19} 34 {64, 76, 69, 41,45}
分割结束。
int Partion(int A[], int low, int high){
int i=low-1;
int p=A[high];
for(int j=low;j<=high;j++){
if(A[j]<=p){
int temp=A[++i];
A[i]=A[j];
A[j]=temp;
}
}
return i;
}
void QuickSort3(int A[], int low, int high){
if(low<high){
int p=Partion(A,low,high);
QuickSort3(A,low,p-1);
QuickSort3(A,p+1,high);
}
}
三种快速排序算法的区别其实就是分割操作的区别。说它有三种快速排序,也只是说它有三种分割操作而已。
分割操作:
将一个数组分为两部分,左半部分的数值都小于等于某一个数p,右半部分的数值都大于等于p。
第一种快速排序:大多数教科书里教给我们的方法,在前一文中已经说明。这里总结一下:
思想:
分割操作:选取数组中的第一个元素作为中位数p,此数将数组分为A[......., p ,........].数组的左半部分的数值都小于或等于p,数组的右半部分都大于或等于p。
然后对数组左右部分再进行递归的分割操作,直到整个数组完全有序为止。
分割操作步骤:
1. 选取A[low]作为中位数p,
2. 从数组的最右端往前找小于等于p的数: A[j]<=p; A[low]=A[j];
3. 再从数组的最左端往后找大小等于p的数:A[i]>=p; A[j]=A[i];
4. 再从数组的第j位置往前找小于等于p的数:A[j]<=p; A[i]=A[j]
5. 重复操作3,4.直到i==j为止。然后将A[i]=p;
分割结束。
例子:
{41, 24, 76, 11, 45, 64, 21, 69, 19, 11}
p=41;
{11, 24, 76, 11, 45, 64, 21, 69, 19, 11}
{11, 24, 76, 11, 45, 64, 21, 69, 19,76}
{11, 24,19, 11, 45, 64, 21, 69, 19, 76}
{11, 24, 19, 11, 45, 64, 21, 69, 45, 76}
{11, 24, 19, 11,21, 64, 21, 69, 45, 76}
{11, 24, 19, 11, 21, 64,64, 69, 45, 76}
{11, 24, 19, 11, 21, 41, 64, 69, 45, 76}
{11, 24, 19, 11, 21}{ 41}{ 64, 69, 45, 76}
分割结束。
int Partion(int A[],int low,int high){ int temp=A[low]; while(low<high){ while(low<high&&temp<=A[high]) high--; A[low]=A[high]; while(low<high&&temp>=A[low]) low++; A[high]=A[low]; } A[high]=temp; return high; } void QuickSort(int A[],int low,int high){ if(low<high){ int p=Partion(A,low,high); QuickSort(A,low,p-1); QuickSort(A,p+1,high); } }
第二种快速排序:
思想:
分割操作:选取p=A[(low+high)/2],作为中位数。将数组分割成A[........,...........]. 左半部分小于等于p,右半部分大于等于p,此时p的位置可能在左半部分中,也可能在右半部分中。
分别对数组的左半部分和右半部分递归进行分割操作,直至数组全部有序。
分割操作步骤:
1. 选取p=A[(low+high)/2]作为中位数
2. 从low往后找到一个大于p的数A[i],从high往前找到一个小于p的数A[j],swap(A[i],A[j]);
3. 直到low>=high为止,分割结束。
例子:
{41, 24, 76, 11, 45, 64, 21, 69, 19, 11}
p=45;
{41, 24, 76,11, 45, 64, 21, 69, 19,
11}
{41, 24, 11,11, 45, 64, 21, 69, 19,
76}
{41, 24, 11, 11,45, 64, 21, 69,
19, 76}
{41, 24, 11, 11, 19,64, 21, 69,
45, 76}
{41, 24, 11, 11,19,64, 21, 69, 45, 76}
{41, 24, 11, 11,19,21, 64, 69, 45, 76}
{41, 24, 11, 11,19,21} {
64, 69, 45, 76}
分割结束。
int Partion(int A[], int low, int high)
{
int middle=A[(low+high)/2];//注意这里不能写成middle=(low+high)/2;下面用A[middle].这样是错的!
//因为low和high值一直在变,所以A[middle]的值也一直在变。
while(1){
while(middle>A[low])low++;
while(middle<A[high])high--;
if(high<=low)
break;
int temp=A[high];
A[high]=A[low];
A[low]=temp;
high--;//如果没有这一步,则如果数组中有两相同的数,该程序会进入无限循环。
low++;
}
return high;//注意这里不能是renturn low;否则无线循环
}
void QuickSort2(int A[],int low,int high){
if(low<high){
int p=Partion(A,low,high);
QuickSort2(A,low,p);
QuickSort2(A,p+1,high);
}
}
第三种排序:
思想和第一种一样。不同就是分割方法。
分割思想:
P=A[high];作为中位数。
处理中的数组:
{{小于p},{大于p},{未处理},{p}}
处理结束后的数组:
{{小于p},{大于p},{p}}
{{小于p},{p},{大于p}}
I作为小于p分数组的最后一位下标,初试为-1;
J作为大于p的分数组的最后一位下标,也是处理中当前处理的元素下标。初始为0;末值为high。
遍历数组j=0;j<high; j++; if(A[j]<p) swap(A[++i],A[j]);
例子:
{41, 24, 76, 11, 45, 64, 21, 69, 19, 34}
P=34;
{41, 24, 76,11, 45, 64, 21, 69, 19, 34}
{24, 41, 76, 11, 45, 64, 21, 69, 19, 34}
{24, 41, 76, 11, 45, 64, 21, 69, 19,34}
{24, 11, 76, 41, 45, 64, 21, 69, 19, 34}
{24, 11, 76, 41, 45, 64, 21,69, 19, 34}
{24, 11, 21, 41, 45, 64, 76, 69, 19, 34}
{24, 11, 21, 41, 45, 64, 76, 69, 19,34}
{24, 11, 21, 19, 45, 64, 76, 69, 41, 34}
{24, 11, 21, 19, 45, 64, 76, 69, 41, 34}
{24, 11, 21, 19} 34 {64, 76, 69, 41,45}
分割结束。
int Partion(int A[], int low, int high){
int i=low-1;
int p=A[high];
for(int j=low;j<=high;j++){
if(A[j]<=p){
int temp=A[++i];
A[i]=A[j];
A[j]=temp;
}
}
return i;
}
void QuickSort3(int A[], int low, int high){
if(low<high){
int p=Partion(A,low,high);
QuickSort3(A,low,p-1);
QuickSort3(A,p+1,high);
}
}
相关文章推荐
- 【快速排序】QuickSort(三种实现方法)c++描述
- 快速排序三种实现方法
- js实现常见的三种排序方法(冒泡排序、快速排序、归并排序)
- 学习笔记:快速排序的C++、JavaScript(2种方法)、Java实现
- 快速排序的三种实现及两种优化
- c++实现数据结构中的各种排序方法:直接插入、选择,归并、冒泡、快速、堆排序、shell排序
- 快速排序的三种实现
- JAVA4——数组的实现及数组的三种排序方法实现
- C++实现模板顺序表和三种排序方法
- 快速排序的两种实现方法
- PB中实现数据窗口动态排序的三种方法
- 详谈排序算法之交换类排序(两种方法实现快速排序【思路一致】)
- PHP基于ICU扩展intl快速实现汉字转拼音及按拼音首字母分组排序的方法
- 快速排序(三种算法实现和非递归实现)
- 快速排序基于不同枢纽的实现方法
- 快速排序的三种不同的实现方式。
- hdoj 1285 确定比赛名次 【拓朴排序】三种方法实现。
- 4、 排序有哪几种方法?请列举。并用JAVA实现一个快速排序.
- (新人上路)成绩单实现对象三种排序方法 及归档解归档方法
- 三种对list排序的方法,并实现动态传递字段名对list进行排序