排序算法总结

常见排序算法评估

时间复杂度

O(n2):冒泡排序、选择排序、插入排序

O(nlogn):归并排序、快速排序、堆排序、希尔排序

O(n):计数排序、基数排序   不是基于比较的排序算法,思想来于桶排序

空间复杂度

O(1):插入排序、选择排序、冒泡排序、堆排序(用递归实现是O(logn))、希尔排序

O(logn~n):快速排序

O(n):归并排序

O(m):计数排序,基数排序(m是“桶”的个数)

稳定性

概念:假定待排序的记录序列中,存在多个具有相同关键字的记录,若经过排序,这些记录的相对次序保持不变,称这种排序算法是稳定的,否则称为不稳定的。

稳定的排序算法:冒泡排序、插入排序、归并排序、计数排序、基数排序、桶排序

不稳定的排序算法:选择排序、快速排序、希尔排序、堆排序


常见排序算法及python实现

快速排序

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快排代码实现需要分割(partition)部分与递归实现部分。

# 快排
def partition(l, left, right):
    k = left
    val = l[right]
    for i in range(left, right):
        if l[i]<val:
            l[i], l[k] = l[k], l[i]
            k += 1
    l[right], l[k] = l[k], l[right]
    return k

def quicksort(l, left, right):
    if left<right:
        k0 = partition(l, left, right)
        quicksort(l, left, k0-1)
        quicksort(l, k0+1, right)
    return l

L = [4,5,6,0,1,7,2,3]
print(quicksort(L,0,len(L)-1))

归并排序

假设序列共有n个元素,将序列每相邻两个数字进行有序合并(merge),形成(n//2+n%2)个序列,排序后每个序列包含两个元素将上述序列再次归并,形成(n//4)个序列,每个序列包含四个元素。重复归并操作,直到所有元素排序完毕。

归并排序代码实现需要有序合并(merge)部分与递归实现部分。

# 归并排序
def merge(a,b):
    c = []
    i = j = 0
    while i<len(a) and j<len(b):
        if a[i]<b[j]:
            c.append(a[i])
            i += 1
        else:
            c.append(b[j])
            j += 1
    if i==len(a):
        for h in b[j:]:
            c.append(h)
    else:
        for h in a[i:]:
            c.append(h)
    return c

def mergesort(l):
    if len(l)<=1:
        return l
    middle = len(l)//2
    left = mergesort(l[:middle])
    right = mergesort(l[middle:])
    return merge(left,right)

L = [4,5,6,0,1,7,3,3]
print(mergesort(L))

TopK

维护大根堆实现,复杂度O(nlogk)

def topk(k):
    return [x for x in reversed([heapq.heappop(data) for x in range(k)])]
def push(elem,data,k):
    if len(data) < k:
        heapq.heappush(data, elem)
    else:
        topk_small = data[0]
        if elem > topk_small:
            heapq.heapreplace(data,elem)
        
k = 7
data = []
list_rand = random.sample(range(1000000), 100)
for i in list_rand:
    push(i,data,k)
print(topk(k))
print(sorted(list_rand, reverse=True)[0:k])  #对比

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值