快排
算法
输入:A[0,...,n-1]
partition(A, p, q) //A待排序的数组,p为某次划分的起始index,q为某次划分的结束index
i<-p
pivot <- A[p]
for j <-p+1 to q
do if A[j] < pivot
then i <- i + 1
A[i]<-->A[j] //A[i]和A[j]交换
A[i]<-->A[p]
return i
QuickSort(A, p, q)
if p < q
then r <- partition(A, p, q)
QuickSort(A, p, r -1)
QuickSort(A, r+1, q)
代码
def partition(a, p, q):
i = p
pivot = a[p]
for j in range(p+1, q+1):
if a[j]<=pivot:
i += 1
tmp = a[i]
a[i] = a[j]
a[j] = tmp
tmp1 = a[i]
a[i] = a[p]
a[p] = tmp1
return i
def quicksort(a, p, q):
if p < q:
r = partition(a, p, q)
quicksort(a, p, r - 1)
quicksort(a, r + 1, q)
时间复杂度
最优情况下,每次pivot都选择到中间大小的数。于是递归表达式有:
T(n)=2T(n/2) + Θ(n)
根据主方法解的T(n)=Θ(n*logn)
最差情况下,A已经处于顺序状态,此时递归表达式有:
T(n)=T(1) + T(n-1) + Θ(n)
通过递归树,可以得到T(n) = Θ(n*n)
归并
算法
DivideList(A, len):
if len > 1
then return a[0,...,len/2], a[len/2,...,len] //可以利用floor对len/2向下取整,就可以不用分支结构判断len奇偶性else
do return [a[0]], [a[1]]
MergeSublist(leftsublist, rightsublist)
leftsublistloc<-0
rightsublistloc<-0
sortedmergelist<-[]
for leftsublistloc<leftsublist.len and rightsublistloc<rightsublist.len
do if leftsublist[leftsublistloc] < rightsublist[rightsublistloc]
then sortedmergelist.append(leftsublist[leftsublistloc] )
leftsublistloc += 1
else
then sortedmergelist.append(rightsublist[rightsublistloc])
rightsublistloc += 1
if leftsublistloc < leftsublist.len
then sortedmergelist.extend(leftsublist[leftsublistloc,...,leftsublist.len])
if rightsublistloc < rightsublist.len
then sortedmergelist.extend(rightsublist[rightsublistloc,...,rightsublist.len])
return sortedmergelist
MergeSort(A, len) //A 待排序的序列,len为该序列长读
if len==1
then return A
else
leftsublist, rightsublist = dividelist(A, A.len)
return mergesublist(mergesort(leftsublist, leftsublist.len), mergesort(rightsublist, rightsublist.len))
代码
def dividelist(a, q):
if q > 1:
return a[0:math.floor(q/2)], a[math.floor(q/2):]
else:
return [a[0]], [a[q]]
def mergesublist(leftsublist, rightsublist):
sortedmergelist = []
leftsublistloc = 0
rightsublistloc = 0
while(leftsublistloc<len(leftsublist) and rightsublistloc<len(rightsublist)):
if leftsublist[leftsublistloc] <= rightsublist[rightsublistloc]:
sortedmergelist.append(leftsublist[leftsublistloc])
leftsublistloc += 1
else:
sortedmergelist.append(rightsublist[rightsublistloc])
rightsublistloc += 1
if(leftsublistloc < len(leftsublist)):
sortedmergelist.extend(leftsublist[leftsublistloc:])
if(rightsublistloc < len(rightsublist)):
sortedmergelist.extend(rightsublist[rightsublistloc:])
return sortedmergelist
def mergesort(a, q):
if q == 1:
return a
else:
leftsublist, rightsublist = dividelist(a, q)
return mergesublist(mergesort(leftsublist, len(leftsublist)), mergesort(rightsublist, len(rightsublist)))
时间复杂度
该算法的递归表达式有:
T(n) = 2T(n/2) + Θ(n)
根据主方法,T(n) = Θ(n*logn)