省考行测快速解题排序2( 二 )


60
72
83
73
88
85
可以看出a[5]前面的数字都小于它 , a[5]后面的数字都大于它 。因此再对a[0…4]和a[6…9]这二个子区间重复上述步骤就可以了 。

对挖坑填数进行总结
1.i =L; j = R; 将基准数挖出形成第一个坑a[i] 。
2.j--由后向前找比它小的数 , 找到后挖出此数填前一个坑a[i]中 。
3.i++由前向后找比它大的数 , 找到后也挖出此数填到前一个坑a[j]中 。
4.再重复执行2 , 3二步 , 直到i==j , 将基准数填入a[i]中 。
照着这个总结很容易实现挖坑填数的代码:
[cpp] view plaincopy

  1. int AdjustArray(int s[], int l, int r) //返回调整后基准数的位置
  2. {
  3. int i = l, j = r;
  4. int x = s[l]; //s[l]即s[i]就是第一个坑
  5. while (i < j)
  6. {
  7. // 从右向左找小于x的数来填s[i]
  8. while(i < j && s[j] >= x)
  9. j--;
  10. if(i < j)
  11. {
  12. s[i] = s[j]; //将s[j]填到s[i]中 , s[j]就形成了一个新的坑
  13. i++;
  14. }
  15. // 从左向右找大于或等于x的数来填s[j]
  16. while(i < j && s[i] < x)
  17. i++;
  18. if(i < j)
  19. {
  20. s[j] = s[i]; //将s[i]填到s[j]中 , s[i]就形成了一个新的坑
  21. j--;
  22. }
  23. }
  24. //退出时 , i等于j 。将x填到这个坑中 。
  25. s[i] = x;
  26. return i;
  27. }

再写分治法的代码:
[cpp] view plaincopy
  1. void quick_sort1(int s[], int l, int r)
  2. {
  3. if (l < r)
  4. {
  5. int i = AdjustArray(s, l, r);//先成挖坑填数法调整s[]
  6. quick_sort1(s, l, i - 1); // 递归调用
  7. quick_sort1(s, i + 1, r);
  8. }
  9. }

这样的代码显然不够简洁 , 对其组合整理下:
[cpp] view plaincopy
  1. //快速排序
  2. void quick_sort(int s[], int l, int r)
  3. {
  4. if (l < r)
  5. {
  6. //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
  7. int i = l, j = r, x = s[l];
  8. while (i < j)
  9. {
  10. while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
  11. j--;
  12. if(i < j)
  13. s[i++] = s[j];
  14. while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
  15. i++;
  16. if(i < j)
  17. s[j--] = s[i];
  18. }
  19. s[i] = x;
  20. quick_sort(s, l, i - 1); // 递归调用
  21. quick_sort(s, i + 1, r);
  22. }
  23. }

快速排序还有很多改进版本 , 如随机选择基准数 , 区间内数据较少时直接用另的方法排序以减小递归深度 。有兴趣的筒子可以再深入的研究下 。
注1 , 有的书上是以中间的数作为基准数的 , 要实现这个方便非常方便 , 直接将中间的数和第一个数进行交换就可以了 。