一、前言
之前一直对快速排序算法感觉很有兴趣,但是一直懒癌发作,对中间数的阀值问题懒得思考,今天静下心,不到半个钟也做好了。果然人啊,不是做不到,就怕懒得动。以后还要多写多练。
二、算法思想
算法每次循环时取某个数为“基准”值,网上有称之为哨兵,我觉得蛮形象的。每次遍历时从前往后,从后往前,将比哨兵小的数放在左边,大于等于哨兵的数放在右边。一次排序后,以哨兵当前位置为分界线将数组切分为两个子数组,左边数组的值都比哨兵小,右边的值都比哨兵大。递归遍历这两个子数组,最终保证所有的元素都排好序。
三、代码实现
我这里选的是最右边的数为基准值。
int quickSort(int a[], unsigned int left, unsigned int right)
{
if(left >= right)
{
return 0;
}
int base = right;
right --;
while(left < right)
{
if(a[left] >= a[base] && a[right] < a[Base])
{
int tmp = a[left];
a[left] = a[right];
a[right] = tmp;
left ++;
right --;
}
else if(a[left] >= a[base] && a[right] >= a[base])
{
right --;
}
else
{
left ++;
}
}
if(left == right)
{
if(a[left] > a[Base])
{
int tmp = a[left];
a[left] = a[Base];
a[Base] = tmp;
quickSort(a, 0, left-1);
quickSort(a, right+1, Base);
}
else if (a[left] == a[Base])
{
quickSort(a, 0, left-1);
quickSort(a, right+1, Base);
}
else
{
quickSort(a, 0, left);
quickSort(a, right+1, Base);
}
}
else //right < left && a[right] < a[Base] < a[left]
{
//right在前,left在后,right 小于left
int tmp = a[Base];
a[base] = a[left];
a[left] = tmp;
quickSort(a, 0, right);
quickSort(a, left+1, Base);
}
return 0;
}
int main()
{
int arr[] = {88,25,64,64,94,39,45,8,38,44,34,51,102,3,4,4,4,5,6,145,23,23,57};
int num = sizeof(arr)/sizeof(int);
quickSort(arr, 0, num-1);
for(int i = 0; i < num; ++i)
{
cout << arr[i] << " ";
}
cout << endl;
getchar();
return 0;
}