作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4046189.html
首先随机选择一个轴,并调整数组内各个数字,使得比轴值大的数在轴的右边,比轴小的数在抽的左边。然后在递归的对左边和右边进行快速排序。
在调整的过程中,可以使用交替填坑的算法。
例如对于序列 4 2 3 0 1 5 第一次随机选择轴值为3。那么首先把轴值与第一个数交换。并保存数值3,得到序列:
3 2 4 0 1 5
p q
现在取两个指针p,q分别指向序列的第一个数和最后一个数。即p指向3,q指向5。现在p指向的数字为坑,可以被替换掉,那么另q指向第一个比轴值小且在p后面的数,即1。那么把1覆盖掉p指向的坑。并且另p++,现在序列变为:
1 2 4 0 1 5
p q
现在q指向的1为坑,现在另p找到第一个比轴值3大的且在q之前的数,即4。那么把4填入q指向的坑中。q--,序列变为:
1 2 4 0 4 5
p q
现在p指向的4为坑,把第一个比轴值3小且在p后面的数为0,那么把0填入坑中,p++,序列变为:
1 2 0 0 4 5
q p
现在p指向的0为坑,发现p>q,那么把轴值填入坑中,即完成了partition的过程。最终序列为:
1 2 0 3 4 5 轴值为3,其左侧的数都比3小,右侧的数都比3大。
然后对序列1 2 3和4 5,递归的调用快速排序算法就可以了。
代码如下,分别实现了递归和非递归的快排。
1 int partation(vector<int> & arr, int l, int r) 2 { 3 int p = rand() % (r - l + 1) + l; 4 int pval = arr[p]; 5 swap(arr[p], arr[l]); 6 while( l < r ) 7 { 8 while( l < r && arr[r] >= pval ) r--; 9 arr[l] = arr[r]; 10 while( l < r && arr[l] < pval ) l++; 11 arr[r] = arr[l]; 12 } 13 arr[l] = pval; 14 return l; 15 } 16 17 void qs_st(vector<int> & arr, int l, int r) 18 { 19 if( l >= r ) return; 20 stack<pair<int, int> > st; 21 int m = partation(arr, l, r); 22 if( m - 1 > l ) st.push(make_pair(l, m - 1)); 23 if( m + 1 < r )st.push(make_pair(m + 1, r)); 24 while( !st.empty() ) 25 { 26 int l = st.top().first; 27 int r = st.top().second; 28 st.pop(); 29 int m = partation(arr, l, r); 30 if( m - 1 > l ) st.push(make_pair(l, m - 1)); 31 if( m + 1 < r ) st.push(make_pair(m + 1, r)); 32 } 33 } 34 35 void qs(vector<int> & arr, int l, int r) 36 { 37 if(l >= r) return; 38 int m = partation(arr, l, r); 39 qs(arr, l, m - 1); 40 qs(arr, m + 1, r); 41 }