最近看完了算法导论的快速排序,今天来梳理梳理快排。希望对想学快速排序的同学能有所帮助。
原理:
快速排序也是分治法思想的一种实现,他的思路是使数组中的每个元素与基准值(Pivot,通常是数组的首个值,A[0])比较,数组中比基准值小的放在基准值的左边,形成左部;大的放在右边,形成右部;接下来将左部和右部分别递归地执行上面的过程:选基准值,小的放在左边,大的放在右边。。。直到排序结束。
步骤:
1.找基准值,设Pivot = a[0]
2.分区(Partition):比基准值小的放左边,大的放右边,基准值(Pivot)放左部与右部的之间。
3.进行左部(a[0] - a[pivot-1])的递归,以及右部(a[pivot+1] - a[n-1])的递归,重复上述步骤。
排序效果:
我的C++实现(原始版本,非随机化快排):
注释中英掺杂,还请见谅~
1 void QuikSort(int arr[], int length){ 2 3 QuikSort(arr,0,length-1); 4 5 } 6 7 //low:数组的左边界值,开始为0 8 //high:数组的右边界值,开始为length-1 9 void QuikSort(int arr[], int low, int high){ 10 if(low>=high){ //递归退出条件:只有一个元素时 11 return; 12 } 13 14 int pivot = arr[low]; 15 int i=low; 16 for(int j=low+1;j<=high;j++){ 17 if(arr[j]<=pivot){ //a[j] is smaller than pivot 18 i++; //a[i] is bigger than pivot 19 if(i!=j){ 20 Swap(arr[i],arr[j]); 21 } 22 } 23 } 24 Swap(arr[low],arr[i]); //Swap pivot to middle position 25 26 //进行分化(partition),递归 27 QuikSort(arr,low,i-1); //a[i] is the pivot now 28 QuikSort(arr,i+1,high); 29 } 30 31 32 void Swap(int &a, int &b){ 33 int temp = a; 34 a = b; 35 b = temp; 36 }
自己制作的GIF动画: 分区(partition)的演示