快速排序作为排序算法中综合效率最高的一种,值得理解其原理。
快排的基本思想如下,举例将数组元素按升序排列:
1、选取一个数组中的任意一个元素作为基准元素,通常是选取第一个,分别使用一个指针指向第一个元素(头指针)和最后一个元素(尾指针);
2、从尾指针开始,将其指向的值与基准元素比较,尾指针向数组头推进,若发现一个小于基准元素,结束此循环,则将其放到基准元素的位置上;
3、从头指针开始,将其指向的值与基准元素比较,头指针向数组尾推进,若发现一个大于基准元素,结束此循环,则将其放到第2步中尾指针指向的位置上;
4、继续执行第2步和第3步,直到头指针和尾指针指向同一个位置,说明数组的此次遍历完毕,此位置就放入基准元素;
5、以基准值得位置为界限,将数组分成了两个数组,一个是从数组头元素到基准元素前一个元素,另一个是从基准元素后一个到数组尾;
6、递归对两个数组重复第2~5步;
过程图暂时略,后补
代码:
#include <stdio.h>
void qiuck_sort(int *arr, int head, int tail) {
int head_ = head;
int tail_ = tail;
if (head_ <= tail_) {
int stand = arr[head];
// 当head_ = tail_ 之时,说明数组已经遍历完成,跳出循环
while (head_ != tail_) {
//从数组尾向前遍历,查找比基准值小的元素
while (arr[tail_] > stand && tail_ > head_)
tail_--;
//将小的元素赋值到基准值所在位置
arr[head_] = arr[tail_];
// 从数组头开始遍历,查找比基准值大的元素
while(arr[head_] < stand && head_ < tail_)
head_++;
// 将比基准值大的元素赋值到上面tail指针指向的位置
arr[tail_] = arr[head_];
}
// 跳出循环之后,将基准值放到head_和tail_共同指向的地方,
arr[head_] = stand;
// 以基准值得位置为界,对前后两个数组继续采用该排序方法,最后排序完成
qiuck_sort(arr, head, head_ - 1);
qiuck_sort(arr + head_, head_ + 1, tail);
}
}
int main() {
int a[5] = {2, 6, 4 ,8 ,3};
int i = 0;
printf("Before sort: \n");
for (i = 0; i < 5; i++)
printf("%d ", a[i]);
qiuck_sort(a, 0, 4);
printf("\nAfter sort: \n");
for (i = 0; i < 5; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
输出 :
[localhost@localhost sort]$ ./quick_sort
Before sort:
2 6 4 8 3
After sort:
2 3 4 6 8
快速排序的时间复杂度为nlogn,最坏情况就是n 2。