快速排序的特点是原地排序,且将长度为N的数组所需的时间和NlgN成正比。
基本算法
快速排序是一种分治的排序算法,将数组排序的方式是当两个子数组都有序时整个数组也就有序了。
快速排序的关键在于切分(partition),先使用切分方法将a[j]放到合适位置,使a[lo]到a[j-1]中的元素都不大于·a[j],a[j+1]到a[hi]的元素都不小于a[j]。然后,再递归调用将其他位置的元素排序。
快速排序的切分
public int Partition(List<int> a, int lo, int hi)
{
var i = lo;
var j = hi + 1;
var compare = a[lo];
while(true)
{
while(a[++i] < compare) if (i == hi) break;
while(compare < a[--j]) if (j == lo) break;
if(i >= j) break;
Exch(a, i, j);
}
Exch(a, lo, j);
return j;
}
快速排序
public void Sort(List<int> a, int lo, int hi)
{
if (hi<=lo ) return;
j = Partition(a,lo,hi);
Sort(a,lo,j-1);
Sort(a,j+1,hi);
}
三向切分的快速排序
对于包含大量重复数据的数组,排序时间能够从线性对数降低至线性时间
def exch(a,i,j):
t=a[i]
a[i]=a[j]
a[j]=t
def sortMethod(a,lo,hi):
if hi<=lo :
return
lt=lo
i=lo+1
gt=hi
v=a[lo]
while i<=gt:
cmp=a[i]-v
if cmp<0:
exch(a,lt,i)
lt+=1
i+=1
elif cmp>0:
exch(a,i,gt)
gt-=1
else:
i+=1
sortMethod(a,lo,lt-1)
sortMethod(a,gt+1,hi)
2.3.15 螺丝和螺帽
条件:
1.N个螺丝与N个螺帽混在一起;
2.快速配对
3.一个螺丝只会配对一个螺帽,反之同理,即无重复数据
4.不能螺丝间比较,或者直接螺母间比较,即只能使用螺母与螺丝比较大小。