其中一直困扰我的一个点就是将元素分成两部分的问题,大部分文章都只讲方法,或者演示方法,但说实话我有点懵,因为我并没有搞清楚为什么这样那样做就能将元素调整为两部分,只是勉强记住了方法。
最近又碰到了这个问题,在网上查了很多资料,感觉终于搞清楚了,总结如下:
方法一:单向调整,最简单易懂
1 /*单向调整,将元素按基准值分成三部分*/ 2 int pa(int a[],int left,int right) 3 { 4 /*为什么要按基准值分成三部分? 5 如何分成两部分的话,某些情况会出现死循环 6 例如将 2 3 4 5 3 分成两部分,得到的将是 |2 3 4 5 3 ,等于没分 7 下次递归会导致 left与mid值相等,进入死循环*/ 8 9 int key=a[left];//选取基准值 10 int t,i,j; 11 /*核心思路:让i左边的元素必须小于key,或者说让小于key的元素都在i左边 12 此循环将元素分成两部分: 13 a[left+1]~a[i-1]小于key,a[i]~a[right]大于等于key*/ 14 for(i=j=left+1;j<=right;j++) 15 { 16 if(a[j]<key) 17 { 18 t=a[i];a[i]=a[j];a[j]=t; 19 i++; 20 } 21 } 22 /*a[left]等于key,a[i-1]肯定小于key,交换后可以保证: 23 i-1左边的元素小于key,i-1指向的元素等于key,i-1右边的元素大于等于key*/ 24 t=a[i-1];a[i-1]=a[left];a[left]=t; 25 return i-1; 26 }