1. 程式人生 > >程式設計之法第二章【快速排序的兩種方法】

程式設計之法第二章【快速排序的兩種方法】

花了兩個多小時重新複習了快速排序,之前以為懂,但是真正實踐的時候才發現自己錯了。

快速排序有兩種實現方式。都是兩個指標,不過之前學的一種是一個從頭開始掃,一個從尾開始掃。另外一種是兩個都是從頭開始掃,不過一個比另外一個前一個位置。

如果真正的理解快排的原理,對於一些排序的問題就會迎刃而解了。

例如奇偶分開,荷蘭國旗(相當於對012排序)

雖說今天花的時間比較多,但是理解了就感覺受益頗多,主要是思想,但是自己的實現能力還是不行。還是要多鍛鍊。

這是《程式設計之法》上的一道題目,將奇偶數分開,不考慮原始順序,我用兩種快排實現,可能還不是很正確,但是思路應該是對的。

#include <iostream>
#include <algorithm>

using namespace std;

bool judge(int a) {
	return (a&1)==1;
}
//快排1 
void OddEvenSort2(int *a,int l,int r) {
	int x=a[r];
	int i=l-1,j=l;
	for(j=l; j<r; j++) {
		if(judge(a[j])) {
			i++;
			swap(a[i],a[j]);
		}
	}
	swap(a[r],a[i+1]);
	for(int i=0; i<=r; i++)
		cout<<a[i]<<" ";
	cout<<endl;
}
//快排2 
void test(int *a,int l,int r){
	int i=l,j=r,x=a[l];
	while(i<j){
		while(i<j&&!judge(a[j])) j--;
		if(i<j){
			a[i]=a[j];
			i++;
		} 
		while(i<j&&judge(a[i])) i++;
		if(i<j){
			a[j]=a[i];
			j--;
		}
	}
	a[i]=x;
	for(int i=0; i<=r; i++)
		cout<<a[i]<<" ";
	cout<<endl;
}
int main() {
	int a[10]= {-121,15,241,-23,-121,57,15161,19,781,111};
	test(a,0,9);
	OddEvenSort2(a,0,9);
}

這是荷蘭國旗這道題,如果能夠理解快排的一種方法,那麼三種指標也容易理解了,難就難在分類討論要準確而已。

三種情況:(F:頭指標,C:當前指標,E:尾指標)

1.當C==0時,和F交換,C++,F++,因為0要放在前面。

2.當C==1時,不用換,C++

3.當C==2時,和E交換,E--,但是C不動,因為他有可能是0或者1,0的話還要和F交換,考慮一下(201012)應該就會明白了。

#include <iostream>
#include <algorithm>

using namespace std;

void flag(int *a,int len)
{
	int f=0,s=0,e=len-1;
	while(s<=e){
		if(a[s]==0){
			swap(a[s],a[f]);
			s++;f++;
		}
		else if(a[s]==1){
			s++;
		}
		else{
			swap(a[s],a[e]);
			e--;
		}
	}
	for(int i=0;i<len;i++)
	cout<<a[i]<<" ";
	cout<<endl;
}

int main(){
	int a[10]={2,0,1,2,0,2,0,1,1,0};
	flag(a,10);
}