Python 排序算法

Python 排序算法

冒泡排序

冒泡排序多次遍历列表,它比较相邻的项并交换那些无序的项。

def bubblesort(nlist):
    for i in range(len(nlist)):
        for j in range(len(nlist)-1):
            if nlist[j+1]<nlist[j]:
                nlist[j],nlist[j+1]=nlist[j+1],nlist[j]
return nlist

选择排序

选择排序每次遍历列表只做一次交换,一个选择排序在它遍历时寻找最大的值,并在完成遍历后将其放在正确的位置。

def selectsort(nlist):
    for i in range(len(nlist)):
        tmp=nlist[i]
        index=i
        for j in range(i,len(nlist)):
            if tmp>nlist[j]:
                tmp=nlist[j]
                index=j
        nlist[i],nlist[index]=nlist[index],nlist[j]
return nlist 

插入排序

插入排序就是每一步将一个待排序数据按大小插入到已经排序的数据中的适当位置,直到全部插入完毕。

def insort(nlist):
    for i in range(1,len(nlist)):
        cur= nlist[i]
        pos=i
        while pos>0 and nlist[pos-1]>cur:
            nlist[pos]=nlist[pos-1]
            pos-=1
        nlist[pos]=cur
return nlist

归并排序

归并排序使用了二分法,归根结底的思想是分而治之。拿到一个长数组,将其不停地分为左边与右边两份,然后以此递归分下去。然后再将它们按照两个有序数组的样子合并起来。

def merge(a,b):
    res=[]
    i=0,j=0
    while i<len(a) and j<len(b):
        if a[i]<b[j]:
            res.append(a[i])
            i+=1
        else:
            res.append(b[j])
            j+=1
    res+=a[i:]+b[j:]
return res
def mergesort(nlist):
    if len(nlist)<=1:
        return nlist
    mid=len(nlist)//2
    left=mergesort(nlist[:mid]
    right=mergesort(nlist[mid:]
    return merge(left,right)

快速排序

在平均情况下,排序n个元素要O(nlogn)次比较,在最坏的情况下,则需要O(n2 ) 次比较,事实上,快排通常比其他O(nlogn)算法更快,因为它的内部循环可以在大部分架构上很有效率地被实现出来。
步骤:

  1. 从序列中挑选一个元素,作为基准。
  2. 把所有比基准值小的元素放在基准的前面,所有比基准值大的元素放在基准的后面,这个称为分区操作。
  3. 对每个分区递归地进行步骤1,2,递归结束的条件是序列的大小是0或者1,这是整体已经排好序了。
def fastsort(nlist,left,right):
    if left<right:
        i=left
        j=right
        base=nlist[i]
        while i<j:
            while i<j and nlist[j]>=base:
                j-=1
            nlist[i],nlist[j]=nlist[j],nlist[i]
            while i<j and nlist[i]<=base:
                i+=1
            nlist[i],nlist[j]=nlist[j],nlist[i]
        nlist[i]=base
        fastsort(nlist,left,i-1)
        fastsort(nlist,j+1,right)
return nlist

堆排序

堆排序是一种完全二叉树,是一种树形选择排序算法,利用大顶堆堆顶元素最大的特点,不断取出最大元素,并调整使剩下的元素还是大顶堆。依次取出最大元素就是排好序的列表。

def fixdown(a,k,n):
    n-=1
    while 2*k<=n:
        j=2*k
        if j<n and a[j]<a[j+1]:
            j+=1
        if a[k]<a[j]:
            a[k],a[j]=a[j],a[k]
            k=j
        else:
            break
def headsort(nlist):
    n=len(nlist)-1
    for i in range(n//2,0,-1):
        fixdown(nlist,i,len(nlist))
    while n>1:
        nlist[1],nlist[n]=nlist[n],nlist[1]
        fixdown(nlist,1,n)
        n-=1
    return nlist[1:]

top K问题:

基于堆排序的top k算法

先建立k大小的最小堆,然后每次将新对象值与堆顶比较,如果比堆顶大,则用新值替换堆顶,并重新维持堆。其时间复杂度为O(nlog(k))。

基于快排的top K算法

如果我们了解快速排序算法的话,知道其原理是每次寻找一个数值,将数组中所有小于这个数的值放在其左侧,所有大于其数值的数放在其右侧。因此调用一次partion之后,设其返回值为p,则比第p个数字小的所有数字在数组的左侧,比p个数字大的所有数字都在数组的右侧。我们可以基于快排的原理用其实现寻找top k的元素。其时间复杂度为O(n)。

posted @ 2019-07-20 19:46  桔梗1992  阅读(216)  评论(0编辑  收藏  举报