算法与数据结构:快速排序法

快速排序法是排序算法中综合性能最好的一种,Java语言和C++语言都自带了快速排序算法的库函数,足以见得其效率。

本次算法的实现思路来自于博客,网上的快速排序实现方式基本有两种形式,其中之一就是本文参考的这一种,还有一种是百度百科里面的哪一种,具体那种更优我觉得差异不大,其核心思路都是一样的。

本文使用的快速排序算法的思路:
从待排序数组中找一个数作为标杆(对于这个数怎么选择众说纷纭,我为了让算法简单选得是每次待排序数组的第一个元素),每一趟快速排序将比标杆大的数放在它的右边,比它小的数放在标杆的左边,实现一轮快速排序。
然后通过递归调用,将标杆左边的数组又作为一个参数,直到需要排序的数组只有一个数为止。

实例:有待排序数组array,其长度为arr_len,其中的数据元素有

1
13,22,58,3,1,2,1

共计有七个个元素,我们以第一个元素13为标杆,进行第一轮快速排序,得到如下结果:

1
1 1 2 3 13 58 22

可以看到,我们将比13大的元素放在了该元素的右边,比13小的元素放在了该元素的左边,但是数组还不是有序的。但程序已经基本有序,我们以13为分割,对13左边和右边的数组再次实现上述过程。

13左边已经有序:

1
1,1,2,3

13右边:

1
2
待排序数组:58,22
排序完成:22,58

由于我们传递的是数组的地址(指针方式)和需要排序的数组的下标,比如13右边的数组传递的就是数组array,start:6,finish:7

程序的大概思路如上所述,下面给出代码实现,本次采用C语言实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
本程序实现对一组整形数的快速排序实现
2018年6月20日 16:38:43
yangchaofu
*/

#include<stdio.h>
#include<stdlib.h>
/*两种数组传递的函数原型*/
void quicksort(int array[],int left,int right);
// void quicksort(int *array,int array_length);

int main(void)
{
int array[]={13,22,58,3,1,2,1};
int arr_len = sizeof array / sizeof array[0];
/*输出数组*/
printf("Array's length: %d\n",arr_len);
for(int i = 0; i < arr_len; i++)
{
printf("%d ",array[i]);
}
putchar('\n');
quicksort(array,0,arr_len-1);
/*排序后的输出结果*/
for(int i = 0; i < arr_len; i++)
{
printf("%d ",array[i]);
}
putchar('\n');
system("pause");
return 0;
}

/*
quicksort函数对给定的数组进行快速排序
*/
void quicksort(int array[],int left,int right)
{
/*递归结束条件,很重要的一个点*/
if(left >= right)
return;
int l = left, r = right;
/*每次排序一需要排序的数组的第一个数作为标杆,将比它大的数放在它的右边,比它小的数放在它的左边(倒序与之相反)*/
int temp = array[left];
while(l != r)
{
/*从右往左找一个比标杆temp小的数,l < r 避免出现l比r大程序还在循环的异常,程序在l==r时需要跳出循环*/
while(array[r] >= temp && l < r)
r--;
/*从左往右找一个比标杆temp大的数*/
while(array[l] <= temp && l < r)
l++;
/*寻找完毕,执行至此,找个一个比标杆小的值array[r]和一个比标杆大的值array[l]*/
if(l < r)
{
/*如果目前找到的比标杆小的值array[r]在比标杆大的值array[l]的右边,即:两数下标 l < r ,则交换两个数*/
int t;
t = array[l];
array[l] = array[r];
array[r] = t;
}
}
/*上面的循环实现快速排序中的比标杆大的数和比标杆小的数的交换,快速排序的交换逻辑可以有多种实现方式
除以上实现方式外,还有标杆在比较中,随着程序的执行进行位置的更换.
本程序实现其中一种逻辑,到目前为止,标杆依旧在数组的最左边,需要将其和l=r这个位置的数进行交换.
*/
int temporary = array[r];
array[r] = temp;
array[left] = temporary;
/*至此,一趟快速排序结束,使用递归重复上述过程
此处递归的写法有两种,使用的r下标实际上与l下标的值是相等的,使用那一个都可以.
*/
for(int i = 0; i < 7; i++)
{
printf("%d ",array[i]);
}
putchar('\n');
quicksort(array,left,r-1);
quicksort(array,r+1,right);
}