快速排序是对冒泡法排序的一种改进。
快速排序算法 的基本思想是:将所要进行排序的数分为左右两个部分,其中一部分的所有数据都比另外一 部分的数据小,然后将所分得的两部分数据进行同样的划分,重复执行以上的划分操作,直 到所有要进行排序的数据变为有序为止。
可能仅根据基本思想对快速排序的认识并不深,接下来以对n个无序数列A[0], A[1]…, A[n-1]采用快速排序方法进行升序排列为例进行讲解。
(1)定义两个变量low和high,将low、high分别设置为要进行排序的序列的起始元素和最后一个元素的下标。第一次,low和high的取值分别为0和n-1,接下来的每次取值由划分得到的序列起始元素和最后一个元素的下标来决定。
(2)定义一个变量val,通 常,val值为要进行排序序列的第一个元素值。第一次的取值为A[0]。
(3)从high所指向的数组元素开始向左扫描,扫描的同时将下标为high的数组元素依次与val进行比较操作,直到high不大于low或找到第一个小于val的数组元素,然后将该值赋值给low所指向的数组元素, 然后就不移动high。
(4)如果low依然小于high,那么由low所指向的数组元素开始向右扫描,扫描的同时将下标为low的数组元素值依次与val进行比较操作,直到low不小于high或找到第一个大于val的数组元素,然后将该值赋给high所指向的数组元素。
(5)重复步骤(3) (4),直到low=high为止,这时成功划分后得到的左右两部分分别为A[low……pos-1]和A[pos+1……high],其中,pos下标所对应的数组元素的值就是val,所以在划分结束时还要将下标为pos的数组元素赋值 为 val。 PS:经过一轮比较,只是找到了val的位置,其他数组元素依然是无序的。
(6)将划分得到的左右两部分A[low……pos-1]和A[pos+1……high]继续采用以上操作步骤进行划分,直到得到有序序列为止。
为了能够加深读者的理解,接下来通过一段代码来了解快速排序的具体实现方法。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define N 6 4 int findPos(int arr[], int low, int high){ 5 int val; 6 val = arr[low]; 7 while(low<high){ 8 while(low <high && arr[high]>= val ) 9 high--; 10 arr[low] = arr[high]; 11 12 while( low<high && arr[low]<=val ) 13 low++; 14 arr[high] = arr[low]; 15 } 16 arr[low] = val; 17 return low; 18 } 19 void quick_sort(int arr[], int low, int high){ 20 int pos; 21 if (low<high){ 22 pos = findPos(arr, low, high); 23 quick_sort(arr,low,pos-1); 24 quick_sort(arr,pos+1,high); 25 } 26 return; 27 } 28 int main(void){ 29 int i; 30 int arr[N]={32,12,7, 78, 23,45}; 31 printf("排序前 \n"); 32 for(i=0;i<N;i++) 33 printf("%d\t",arr[i]); 34 quick_sort(arr,0,N-1); 35 printf("\n 排序后 \n"); 36 for(i=0; i<N; i++) 37 printf("%d\t", arr[i]); 38 printf ("\n"); 39 system("pause"); 40 return 0; 41 }
运行结果:
排序前 32 12 7 78 23 45 排序后 7 12 23 32 45 78
在上面的代码中,根据前面介绍的步骤一步步实现了快速排序算法。接下来通过示意图来演示快速排序。
1>开始是:
2>因为high指向的45比32大,所以high往左移
3>因为high指向的23比32小,所以把23赋值给low
4>因为low指向的23比32小,所以向右移low
5>因为low指向的12比32小,所以向右移low
6>因为low指向的7比32小,所以向右移low
7>因为low指向的78比32大,所以把78赋值给high
8>因为high指向的78比32大,所以向左移high
9>至此low和high重合,low的位置就是Val的最终位置
10>然后low到pos-1范围内的数组元素,再按上述的操作做排序
11>然后pos+1到high范围内的数组元素,再按上述的操作做排序