数组排序(5) 快速排序之三指针分区法

论坛 期权论坛 脚本     
匿名技术用户   2020-12-28 07:58   11   0

目录

算法思想

三指针分区法

代码实现(Java)

时间复杂度


算法思想

当所有数的左边的数据都小于等于这个数,右边的数据都大于这个数时,数组就有序了。

三指针分区法

  1. 先初始化主元为首元,然后初始化三个指针:smaller和equal都初始化为下标为数组第二个、bigger初始化为尾元。smaller为扫描指针,每次移动smaller
  2. 当smaller扫描到的数字小于主元,则下标为smaller和equal的需要交换数据,这样就又将小于主元的放在一起了,然后smaller和equal都要自增
    当smaller扫描到的数字等于主元,直接将smaller自增
    当smaller扫描到的数字大于主元,就将小标为smaller和bigger上的数据交换,bigger再自减(和单向扫描分区法处理一样)
  3. 直到smaller已经超过了bigger,这时候(equal-1)指向的是最后一个小于等于主元的数,交换首元与(equal-1)上的数据
  4. 将小于主元和大于主元的两个数组进行快速排序
  5. 32分16,16分8,8分4,4分2,2分1,当左右两边数组的长度为0时,这个数组就已经排好序了

代码实现(Java)

 private static void sort(int[] array, int start, int end) {
  //初始化三指针
  //小于主元的指针和等于主元的指针都初始化为下标为数组第二个
  //大于主元的指针初始化为尾元
  int smaller = start+1;
  int equal = smaller;
  int bigger = end;
  //设置退出条件
  if(smaller > bigger) return ;
  //选择主元,一般为首元
  int num = array[start];
  /*
   * 当smaller扫描到的数字小于主元,则下标为smaller和equal的需要交换数据,这样就又将小于主元的放在一起了,然后smaller和equal都要自增
   * 当smaller扫描到的数字等于主元,直接将smaller自增
   * 当smaller扫描到的数字大于主元,就将小标为smaller和bigger上的数据交换,bigger再自减(和单向扫描分区法处理一样)
   */
  while(smaller <= bigger) {
   if(array[smaller] < num) {
    swap(array, equal, smaller);
    equal++;
    smaller++;
   }
   else if(array[smaller] == num) {
    smaller++;
   }
   else if(array[smaller] > num) {
    swap(array, smaller, bigger);
    bigger--;
   }
  }
  //交换首元与right上的数
  swap(array, start, equal-1);
  //继续将right两边的数组进行快速排序
  sort(array, start, equal-2);
  sort(array, bigger+1, end);
 }
 
 private static void swap(int[] array, int sc, int r) {
  int num = array[sc];
  array[sc] = array[r];
  array[r] = num;
 }

时间复杂度

每次处理数组的一半,一共要处理logn次,每次处理要扫描n个数据,所以时间复杂度为O(nlogn)

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP