为了以防万一有人想不开想手撕快排呢?比如我。
通过快排来理解二分思想
什么是快排?
快排的思想不难,理解好递归很重要。
什么是递归?
递归,就是在运行的过程中调用自己。
构成递归需具备的条件:
- 子问题须与原始问题为同样的事,且更为简单;
- 不能无限制地调用本身,须有个出口,化简为非递归状况处理。
什么是二分?
“一尺之捶,日取其半,万世不竭” 相信你不陌生吧?这是来自《庄子·天下》中惠施的一句名言。说的就是二分(有的时候不得不感慨古人的智慧啊!)
将一项大任务,不断自截两半,调用相同的处理函数分别处理,截到什么时候呢?截到可以解决这个问题为止。
快排的思想
很多时候我们使用二分法,并不知道它的最小单位是多少,为什么会对这个最小的段没有感觉呢?
因为我们需要关注的不过三个点,首,尾,和我们要取到的中点。假设这个中点为i
,下次递归就是left
到i-1
和i+1
到right
搞清楚这三个点之后,具体分到多小了,就不是那么重要了。
接下来我们要关注的就是“退出” 的时机。在快排里,当首尾指针相遇,就是我们该停止的时候。在代码里体现是:
if (l > r)
{
return;
}
其中l
是左指针,r
是右指针。
C语言实现快排
#include<stdio.h>
int a[100], n;
void quicksort(int l, int r)
{
int i, j, t, temp;
if (l > r)
{
return;
}
temp = a[l];//基准数
i = l;
j = r;
while (i != j)
{
while (a[j] >= temp && i < j)
{
j--;
}
while (a[i] <= temp && i < j)
{
i++;
}
if (i < j)
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
a[l] = a[i];
a[i] = temp;
quicksort(l, i - 1);
quicksort(i + 1, r);
}
int main()
{
int i, j, t;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
quicksort(1, n);
for (i = 1; i <= n; i++)
{
printf("%d ", a[i]);
}
return 0;
}
/*
11
6 2 1 7 9 3 4 5 10 8 5
*/
运行结果: