快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,
整个排序过程可以递归进行,以此达到整个数据变成有序序列。
不考虑效率的代码A如下:
void QuickSort(int a[],int size)
{
if (size == 0 || size == 1)
{
return; //一个不排序
}
int * pbuf = new int[size];
memcpy(pbuf,a,size);
int nFist = a[0];
int m = 0;
int n = size-1;
for (int i =1;i<size;i++)
{
TRACE("%d,",a[i]);
if (a[i]<nFist)
{
pbuf[m++] = a[i];
}
else
{
pbuf[n--] = a[i];
}
}
pbuf[m] = a[0];
for (int i =0;i<size;i++)
{
TRACE("%d\n",*(pbuf+i));
}
memcpy(a,pbuf,size*4);
int nPos = m;
if (pbuf)
{
delete []pbuf;
}
for (int i =0;i<size;i++)
{
TRACE("%d,",a[i]);
}
//0-1-....npos...size-2-size-1
QuickSort(a,nPos);
QuickSort(a+nPos+1,size-1-nPos);
}
上面的代码思路很清晰,准备一个BUF,比关键字大的从后往前插入,比关键字小的从前往后插入,最后留一个空插入关键字,再递归调用。代码虽然容易懂,但是多次开辟空间,降低了
效率。
标志的写法B如下:
//快速排序
void quick_sort(int s[], int l, int r)
{
if (l < r)
{
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r, x = s[l];
while (i < j)
{
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}
代码B采用交换的方式,确保比关键字小的在左边,比关键字大的在右边,只需要很少的空间保存关键字,也是采用递归,但效率高。