归并排序
归并排序与上述基于交换、选择等排序的思想不一样,“归并”的含义是将两个或者两个以上的有序表组合成一个新的有序表。假定待排序表含有n个记录,则可将其视为n个有序的子表,每个子表的长度为1,然后将其两两归并,得到[n/2]个长度为2或1的有序表;再两两归并,得到长度为4或1~3的有序表…重复,直到得到一个长度为n的有序表为止,这种排序的方式称为2路归并排序。
merge()的功能是将前后相邻的两个有序表合并成呢个一个有序表。设两段有序表A[low, mid], A[mid+1, high]存放在同一顺序表的相邻位置。先将他们复制到辅助数组B中。
每次从对应B中的两个段取出一个记录进行关键字的比较,将较小值放入A中,当数组B中有一段的下标越界时,将另一段的剩余部分直接复制到A中。
def merge(alist, low, mid, high):
"""
表alist的两段各自有序,将他们合并成个一个有序表
"""
temp = [0 for _ in range(len(alist))]
for k in range(low, high + 1):
# 将alist中所有元素复制到temp中
temp[k] = alist[k]
i, j = low, mid + 1
k = i
while i <= mid and j <= high:
if temp[i] <= temp[j]:
# 比较temp的左右两段元素
# 将较小值复制到alist中
alist[k] = temp[i]
i += 1
else:
alist[k] = temp[j]
j += 1
k += 1
while i <= mid:
# 若第一个表未检测完,复制
alist[k] = temp[i]
k += 1
i += 1
while j <= high:
# 若第二个表未检测完,复制
alist[k] = alist[j]
k += 1
j += 1
一趟归并排序的操作是,调用[n / 2h]次算法merge(),将L[1…n]中前后相邻且长度为h的有序段进行两两归并,得到前后相邻,长度为2h的有序段,整个归并排序需要进行log(n)趟。
def merge_sort(alist, low, high):
if low < high:
mid = (low + high) // 2
merge_sort(alist, low, mid)
merge_sort(alist, mid+1, high)
merge(alist, low, mid, high)
算法分析
基数排序
基数排序是一种很特别的排序方法,它不基于比较进行排序,而采用多关键字排序思想(即基于关键字各位大小进行排序)。借助分配和收集两种操作堆单逻辑关键字进行排序。基数排序又分为最高位优先(MSD)和最低位优先排序(LSD)排序。
基数排序的原理就是,先排元素的最后一位,再排倒数第二位,直到所有位数都排完。这里并不能先排第一位,那样最后依然是无序
算法分析
时间复杂度:基数排序需要进行d趟分配和收(d为位数),一趟分配需要O(N)O(N)O(N),一趟收集需要O(r)O(r)O(r),r为队列数,即每一位上的种类数,O(a(n+r))O(a(n+r))O(a(n+r)),它与序列的初始状态无关。
空间复杂度:一趟排序需要用到的辅助空间为r个队列,但以后的排序会重复使用。故空间复杂度为O(r)O(r)O(r)。
稳定
小编这里整理了一些Python学习资料需要的小伙伴可以点击下方获取
小白到大牛,这份资料让你15天到位。稳~www.jianshu.com