基本思想是:
1.先从数列中取出一个数作为基准数pivot。
2.分区过程,将比这个数大的数全放到pivot的右边,”小于或等于它的数全放到pivot的左边“。
3.再对左右区间重复第二步,直到各区间只有一个数。
难点在第2步:找到pivot的位置。pivot理解成中间值,是数列的中间某位置上。pivot左边的数小于它,pivot右边的数大于它。
实现:从左右两端开始挑毛病,不符合自己标准的放到对方的队伍中。在步骤1中取数列左边第一个数作为pivot,此时左一的状态是“空位”的,从最右边开始找不大于pivot的数,放到左边空位。此时,最右边的位置空着了,从左边找不小于pivot的数,放到最右边。左边有空位了,再从右边剩下的位置找小于pivot的数...... 当左右遍历相遇时,就是pivot的位置了!
发明算法的人是如何想到的,我们就不用研究了,能用代码实现它,就够了。
1 void quick_sort(int s[],int l,int r) 2 { 3 if(l < r) 4 { 5 int i = l,j = r, pivot= s[l]; 6 7 while(i < j)//当i=j时,即是pivot的位置 8 { 9 while(i < j && s[j] >= pivot) 10 j--; 11 if(i < j) 12 s[i++] = s[j]; 13 14 while(i < j && s[i] < pivot) 15 i++; 16 if(i < j) 17 s[j--] = s[i]; 18 } 19 s[i] = pivot; 20 quick_sort(s, l, i-1); 21 quick_sort(s, i+1, r); 22 } 23 24 25 }
优化:
1. 步骤1 中基准pivot的选取,可以用“三数取中”法。即数列的左端,右端,中间三个数取中间大小的。
2. 数组元素个数少时,最好用直接插入排序。
未完待续。。。。。。