问题引入
快速排序法(quick sort)是公认的最快的排序方法之一(根据不同的待排序对象而定),虽然快速排序法在最差状况下时间复杂度可以达O(n²),但是在多数的情况下,快速排序法的效率是比较高的。
在 快速排序算法(形式1)中(点击查看),每次将最左边的元素设为中心点,因为快速排序算法的排序效率在于中心点的选择,如果我们将中心点设置为基准元素,使其他元素与其比较,可进一步提高快速排序算法的排序效率。
如果你想要进行深层次的了解和学习,请在分类栏中点击“算法”并找到“快速排序算法(形式3)”进行了解。
问题分析
如下所示,取中间的元素s作比较,同样的先得右找比s大的索引 i,然后找比s小的 索引 j,只要两边的索引还没有交会,就交换 i 与 j 的元素值,这次不用再进行轴的交换了, 因为在寻找交换的过程中,位于中心点位置的元素也会参与交换的动作。
例如:
“橙色”表示要交换的数,“[红色]”表示中心点:
41 24 76 11 [45] 64 21 69 19 36
首先left为0,right为9,(left+right)/2 = 4(取整数的商),所以中心点为下标是4的位置,比较的元素是 45,往右找比45大的,往左找比45小的进行交换。如下表过程:
41 | 24 | 36 | 11 | 45 | 64 | 21 | 69 | 19 | 76 |
41 | 24 | 36 | 11 | 19 | 64 | 21 | 69 | 45 | 76 |
[41 | 24 | 36 | 11 | 19 | 21] | [64 | 69 | 45 | 76] |
完成一次排序后,再分别对左边括号与右边括号的部份进行递回就可以完成排序的目的。
代码实现
说明:采用C语言,编译环境为DevC++。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t; t = x; x = y; y = t;}
void quicksort(int[], int, int);
int main(){
int number[MAX] = {0};
int i, num;
srand(time(NULL)); //时间
printf("排序前:");
for(i = 0; i < MAX; i++){
number[i] = rand() % 100;
printf("%d ", number[i]);
}
quicksort(number, 0, MAX-1);
printf("\n排序后:");
for(i = 0; i < MAX; i++){
printf("%d ", number[i]);
}
printf("\n");
return 0;
}
void quicksort(int number[], int left, int right){
int i, j, s;
if(left < right){
s = number[(left+right)/2];
i = left - 1;
j = right + 1;
while(1){
while(number[++i] < s); // 向右找
while(number[--j] > s); // 向左找
if(i >= j){
break;
}
SWAP(number[i], number[j]);
}
quicksort(number, left, i-1); // 对左边进行递回
quicksort(number, j+1, right); // 对右边进行递回
}
}
运行结果
说明:仅截取了一次过程,可在运行过程中查看,也可根据需要对代码部分进行调整。
写在最后:
读两遍下来,如果仍然有不清楚的地方,可在评论区留言。
如果你有其他感到困惑的问题,欢迎留言。