分割
Partition 分割
函数partition(A,p,r)是一个可以将序列A【p…r】分割成A【p…q - 1】和A【q + 1…r】两部分并返回下标q的值的函数。并且能让A【p…r】中A【p…q - 1】的元素均小于A【q + 1…r】的所有元素。
例如:13 19 9 5 12 8 7 4 21 2 6 11 这个序列我们取最右边的一个元素为基准x,并设i为小于x的所有元素最右边的元素的下标,j为所有大于x的所有元素最右边的元素下标+1;初始化为p-1,j初始化为p,可将序列分为小于等于x,和大于x两个部分,经以下步骤可得序列c。
步骤一:<-( i ) 13<-( j ) 19 9 5 12 8 7 4 21 2 6 11 比较A【j】和 x 的值,明显A【j】大,所以只用将j++,把A【j】分到大于x的序列;
步骤二:<-( i ) 13 19<-( j ) 9 5 12 8 7 4 21 2 6 11 比较A【j】和 x 的值,明显A【j】大,所以只用将j++,把A【j】分到大于x的序列;
步骤三:9<-( i ) 19 13 5<-( j ) 12 8 7 4 21 2 6 11 比较A【j】和 x 的值,明显A【j】小,所以要将i++,然后交换A【i】和A【j】的值,再j++,把A【j】分到小于x的序列;
步骤四:9 5<-( i ) 13 19 12<-( j ) 8 7 4 21 2 6 11 比较A【j】和 x 的值,明显A【j】小,所以要将i++,然后交换A【i】和A【j】的值,再j++,把A【j】分到小于x的序列;
步骤五:9 5<-( i ) 13 19 12 8<-( j ) 7 4 21 2 6 11 比较A【j】和 x 的值,明显A【j】大,所以只用将j++,把A【j】分到大于x的序列;
步骤六:9 5 8<-( i ) 19 12 13 7<-( j ) 4 21 2 6 11 比较A【j】和 x 的值,明显A【j】小,所以要将i++,然后交换A【i】和A【j】的值,再j++,把A【j】分到小于x的序列;
步骤七:9 5 8 7<-( i ) 12 13 19 4<-( j ) 21 2 6 11 比较A【j】和 x 的值,明显A【j】小,所以要将i++,然后交换A【i】和A【j】的值,再j++,把A【j】分到小于x的序列;
步骤八:9 5 8 7 4<-( i ) 13 19 12 21<-( j ) 2 6 11 比较A【j】和 x 的值,明显A【j】小,所以要将i++,然后交换A【i】和A【j】的值,再j++,把A【j】分到小于x的序列;
步骤九:9 5 8 7 4<-( i ) 13 19 12 21 2<-( j ) 6 11 比较A【j】和 x 的值,明显A【j】大,所以只用将j++,把A【j】分到大于x的序列;
步骤十:9 5 8 7 4 2<-( i ) 19 12 21 13 6<-( j ) 11 比较A【j】和 x 的值,明显A【j】小,所以要将i++,然后交换A【i】和A【j】的值,再j++,把A【j】分到小于x的序列;
步骤十一:9 5 8 7 4 2 6<-( i ) 12 21 13 19<-( j ) 11然后直接将A【i+1】和A【r】交换,返回i+1就可以了;
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 int a[1000]; 6 7 int partition(int l,int r){ 8 int x = a[r]; 9 int i = l-1; 10 for(int j = l;j < r; j++){ 11 if(a[j] <= x){ 12 i++; 13 swap(a[i],a[j]); 14 } 15 } 16 swap(a[i+1],a[r]); 17 return i+1; 18 } 19 20 int main(){ 21 int n; 22 scanf("%d",&n); 23 for(int i = 1;i <= n; i++){ 24 scanf("%d",&a[i]); 25 } 26 int k = partition(1,n); 27 for(int i = 1;i <= n; i++){ 28 if(i == k)printf("[%d] ",a[i]); 29 else printf("%d ",a[i]); 30 } 31 }