今天又写qsort,竟然憋了很久写不出来,最后翻了先前的代码。
可见程序算法是容易忘记得。今天再注释一遍,希望以后忘得慢点。
#include <stdio.h>
/*
这个函数没啥好说的
*/
void swap (int *a, int i, int j)
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
/*
设<表示小于或等于end的数,>表示大于end的数,*表示未知大小的数,运行中下标指向是这个样子:
《 《 《 》》 》 》 * * *
p i j r
思路就是用j来遍历数组,从中选出小于a[end]的与小于等于a[end]的右端第一个数既a[i+1]交换,直到最后分组完成。
注意比较巧妙的地方是一开始指针i为start-1;可以符合所有的数都大于end的情况,此时i+1正好还是指向第一个大于a[end]的数
否则 如果i一开始就置为start,那么很可能会使下面的swap (a, i+1, end)出错。
*/
int partition (int *a, int start, int end)
{
int j;
int i = start - 1;
for (j=start; j<end; j++)
{
if (a[j] <= a[end])
{
swap(a, ++i, j);
}
}
swap(a, i+1, end);
return i+1;
}
/*
这个递归调用的函数比较好理解,注意的地方是参数的设置,要想到递归过程中每次都要使用新的start和end,所以partition函数要有这
两个参数。
*/
void quicksort (int *a, int start, int end)
{
int mid;
if (start < end)
{
mid = partition (a, start, end);
quicksort (a, start, mid-1);
quicksort (a, mid+1, end);
}
}
int main ()
{
int i;
static int a[8] = {5, 7, 2, 0, 4, 5, 3, 9};
int len = sizeof(a) / sizeof(a[0]);
for (i=0; i<len; i++)
printf ("%d ", a[i]);
printf ("\n");
quicksort (a, 0, len - 1);
for (i=0; i<len; i++)
printf ("%d ", a[i]);
printf ("\n");
return 0;
}