- 双指针法
把第一个数据取下来,作为key。
一个指针从尾开始找比key小的数
一个指针从头开始找比key大的数
如果找到,就交换两个数。
最好,把key和尾指针指向的数交换。
void Swap (int* x,int* y){
int tmp = x;
x = y;
y = tmp;
}
int PartSort1 (int* a, int left, int right){
int key = a[left];
int begin = left;
int end = right;
while (begin<end){
while (a[end]>key && begin<end){
--end;
}
while (a[begin]<key && begin<end){
++begin;
}
Swap(&a[begin],&a[end]);
}
Swap(&a[end],&a[left]);
return end;
}
- 挖坑法
取第一个数据key,拿出来,把第一个位置作为坑
一个指针从尾开始找比key小的数,找到以后,放在坑里,该指针所在的位置作为新的坑
另一个指针从头开始找比key大的数,找到以后,放在坑里,该指针所在的位置作为新的坑
直到头尾指针相遇
然后把第一个数据放在最后一个坑里
int PartSort2 (int* a, int left, int right){
int key = a[left];
int begin = left;
int end = right;
while (begin<end){
while(a[end]>key && begin<end){
end--;
}
a[begin] = a[end];
while(a[begin]<key && begin<end){
begin++;
}
a[end] = a[begin];
}
a[end] = key;
return end;
}
- 前后指针法
取第一个数据key,让prev指向第一个数据,让cur指向第二个数据。
cur一次遍历每一个数据,如果cur所指向的数据比key小,就把它和prev++所指向的数据交换,没交换一次,prev++
最后,让prev所指向的数据和key交换。
int PartSort3 (int* a, int left, int right){
int key = a[left];
int cur = left+1;
int prev = left;
while (cur<=right){
if (a[cur]<key && ++prev!=cur){
Swap(&a[cur],&a[prev]);
}
++cur;
}
Swap(&a[prev],&a[left]);//交换数据时,传的是实际数据的地址,不能用key代替。
return prev;
}
4.对取key的优化
利用三数取中法,取三个数据中,中间值得数的下标。
int GetMiddle (int* a, int left, int right){
int mid = left + ((left-right)>>1);
if (a[left]<a[right]){
if (a[mid]<a[left]){
return left;
}
else if (a[mid]>a[left]){
return mid;
}
else{
return right;
}
}
if (a[left]>a[right]){
if(a[mid]<a[right]){
return right;
}
else if (a[mid]>a[right]){
return mid;
}
else{
return left;
}
}
}
- 代码实现:
void QuickSort (int* a, int left, int right){
if (left>=right){
return;
}
int div = PartSort1(a,left,right);
QuickSort (a,left,div-1);
QuickSort (a,div+1,right);
}
int main ( ){
int n=10;
int a[n]={0};
srand(timt(0));
for (i=0;i<n;i++){
a[i] = rand();
}
QuickSort (a,0,n-1);
for (i=0;i<n;i++){
printf ("%d ",a[i]);
}
printf ("\n");
}