普林斯顿大学算法课 Algorithm Part I Week 3 重复元素排序 - 三路快排 Duplicate Keys

很多时候排序是为了对数据进行归类,这种排序重复值特别多

  • 通过年龄统计人口
  • 删除邮件列表里的重复邮件
  • 通过大学对求职者进行排序

若使用普通的快排对重复数据进行排序,会造成N^2复杂度,但是归并排序和三路快排就没有这样的问题。

归并排序对重复数据排序的比较在1/2NlgN和NlgN之间

三路快排

目标:将数据分成三个区间(3-way partitioning)

  • lt和gt区间内的元素都和比较元素v相等
  • lt左边的元素都比v小
  • gt右边的元素都比v大

性能

三路快排的复杂度比普通快排小,主要取决于数据中重复数据的数量。重复数据越多,三路快排的复杂度就越接近于N。

Java实现

private static void sort(Comparable[] a, int lo, int hi)
{
  if (hi <= lo) return;
  int lt = lo, gt = hi;
  Comparable v = a[lo];
  int i = lo;
  while (i <= gt)
  {
    int cmp = a[i].compareTo(v);
    if     (cmp < 0) exch(a, lt++, i++);
    else if (cmp > 0) exch(a,i,gt--);
    else              i++;
  }

  sort(a, lo, lt - 1);
  sort(a, gt + 1, hi);    
}

 

  • a[i]  <  v:交换a[lt]和a[i],lt和i分别递增1
  • a[i]  >  v:交换a[gt]和a[i],gt递减1
  • a[i] == v:i递增1
  • 注:gt不自主扫描,是通过a[i]和a[gt]交换后,gt的值才递减

 

posted on 2014-10-02 12:11  Jimtastic  阅读(417)  评论(0编辑  收藏  举报