快速排序是一种非常不错的排序算法,在大多数情况下能够快速地完成排序,所以叫快速排序(废话),
该算法实际上就是为基准元素pivot寻找正确索引的过程,为深入贯彻落实这种思想,下面我们将用一个例子来验证
1 . 我们有一个数组A,要进行排序
int A[] = { 3 , 5 , 8 , 1 , 2 , 9 , 4 , 7 , 6 };
2 . 先设置左标记和右标记,分别指向数组最左边和最右边的元素,再取最右边一个元素A[8]为基准pivot
3 . 我们把左标记向右移动,直到左标记所指向的元素大于或等于pivot就停止移动
4 . 现在移动右标记,我们把右标记向左移动,直到右标记指向的元素小于pivot
5 . 交换两个标记所指向的元素
6 . 重复第3、4步,如果移动右标记时左右标记相等(也就是说右标记撞到左标记)时停下
现在我们把左或右标记指向的元素与pivot交换
交换后我们可以看见6前面的数字都比6小,6后面的元素都比6大,这样我们便找到了6在数组A中正确的位置,现在数组被分成了2个部分,我们递归地对这2部分进行第2-6步操作,直到所有元素排序完成
测试例程:
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
void quicksort(int *arr,int l,int r)
{
int left,right,pivot,tmp;;
if(l < r)
{
left = l;
right = r;
pivot = arr[right];//最右边一个元素作为基准
while(left < right)
{
while(!(arr[left] >= pivot))left++;//左标记向右移动,直到左标记所指向的元素>=pivot就停止移动
while(left < right && !(arr[right] < pivot))right--;//右标记向左移动,直到右标记指向的元素<pivot
if(left < right)
{
tmp = arr[left];//交换左右标记
arr[left] = arr[right];
arr[right] = tmp;
}
}//如果左右标记不相等就重复3、4步
arr[r] = arr[left];//交换左或右标记指向的元素与pivot
arr[left] = pivot;
quicksort(arr,l,left-1);//排序前半部分
quicksort(arr,left+1,r);//排序后半部分
}
}
void bubblesort(int *arr,int num)
{
int i,j,k;
for(i=0;i<num;i++)
{
for(j=0;j<num-1;j++)
{
if(arr[j+1] < arr[j])
{
k = arr[j+1];
arr[j+1] = arr[j];
arr[j] = k;
}
}
}
}
int main()
{
int test1[20000];
int test2[20000];
int i,t;
int CLOCKS_PER_MS;
CLOCKS_PER_MS = CLOCKS_PER_SEC / 1000;
for(i=0;i<20000;i++)//生成测试数据
{
test1[i] = rand();
test2[i] = test1[i];
}
t = clock();
quicksort(test1,0,20000-1);
printf("quicksort = %.3f ms\n",(float)(clock()-t) / CLOCKS_PER_MS);//快速排序用时
t = clock();
bubblesort(test2,20000);
printf("bubblesort = %.3f ms\n",(float)(clock()-t) / CLOCKS_PER_MS);//冒泡排序用时
return 0;
}
采用冒泡排序和快速排序对相同的数据进行排序,结果如下