欢迎大家访问我的微博:http://weibo.com/u/2887401030
快速排序的基本思想是:用过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可对这两部分继续排序,已达到整个序列有序的目的。
直接来看代码:
#include<stdio.h>
#include<stdlib.h>
void printAll(int *a,int len)
{
int i;
if(a == NULL || len < 0)
{
return;
}
for(i=0;i<len;i++)
{
printf("%d ",a[i]);
if((i+1)%10 == 0)
printf("\n");
}
}
void swap(int *a,int i,int j)
{
int tmp;
if(a == NULL || i < 0 || j < 0)
{
return;
}
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
//交换顺序表中字表的记录,是枢轴记录到位,并返回期所在位置
//此时在他之前(后)的记录均不大(小)于它
//假设是:50,10,90,30,70,40,80,60,20
int Partition(int *a,int low,int high)//low=0,high=8
{
int pivotkey;
pivotkey = a[low];//用于字表的第一个记录作枢轴记录
while(low < high)
{
while(low < high && a[high] >= pivotkey)
high--;//注意这里是一直循环,知道a[high]都比pivotkey小
swap(a,low,high);//将比枢轴记录小的记录交换到低端
while(low < high && a[low] <= pivotkey)
low++;
swap(a,low,high);
}
return low;//返回枢轴位置
}
void QSort(int *a,int low,int high)
{
int pivot;
if(low < high)
{
//第一次是50的pivot
//20 10 40 30 50 70 80 60 90
pivot = Partition(a,low,high);
QSort(a,low,pivot-1);//20 10 40 30 对这个的递归
QSort(a,pivot+1,high);//70 80 60 90 //对这个的递归
}
}
/*
对20 10 40 30的递归判断(有利于理解递归分支):
pivotkey=20
1.
20 10 40 30
low high
swap
10 20 40 30
low high
10 20 40 30
low
high
return pivot 1
QSort(a,0,0);low !< high,这个栈退出,
返回到这:
QSort(a,2,3); ...继续
之后返回到70 80 60 90
*/
void QuickSort(int *a,int len)
{
if(a == NULL || len <= 0)
{
return;
}
QSort(a,0,len-1);
}
int main()
{
int a[] = {50,10,90,30,70,40,80,60,20};
int len = sizeof(a)/sizeof(*a);
printf("before sort:\n");
printAll(a,len);
QuickSort(a,len);
printf("\nafter sort:\n");
printAll(a,len);
return 0;
}
结果:
before sort:
50 10 90 30 70 40 80 60 20
after sort:
10 20 30 40 50 60 70 80 90
结果在意料之中,从小到大排序成功。
这段代码的核心函数就是两个,int Partition(int *a,int low,int high)和void QSort(int *a,int low,int high)。
Partition函数就是将选取到的pivotkey不断交换,将将比他小的换到他的左边,比他大的换到他的右边,他也在变换中不断跟新自己的位置,知道完全满足这个要求为止。我上面的代码中有一块注释,就是讲解这个变化过程。可以仔细看看,不过没有推完,大家可以自己试试。
QSort函数就是递归调用Partition,第一次是50,10,90,30,70,40,80,60,20,Partition后返回4。再递归QSort(a,0,3);//20,10,40,30 ,递归完成后,再是QSort(a,5,8);//70,80,60,90,递归完成后,排序完成,退出。
总的来说,快速排序的思想不是很难。实现代码因为是递归,也还好。大家只要多想想,应该都能明白。
原文地址:http://blog.csdn.net/tomjohnson/article/details/44809369