排序算法_Python实现汇总

以下的排序算法都是基于关键码排序的,所以在比较关键码大小的时候,代码中都使用了.key。item.key表示item的关键码。在实际应用的时候需要对代码进行适当的修改。直接对数组进行排序的时候,只需要将.key去掉,直接比较元素的大小即可。


""" 
coding: utf-8
@author: zhangxiang
"""

# 插入排序  O(n2)   (稳定,适应)
def insert_sort(lst):
    for i in range(1,len(lst)):
        x = lst[i]
        j = i
        while j>0 and lst[j-1].key > x.key:
            lst[j] = lst[j-1]
            j = j - 1
        lst[j] = x

# 直接选择排序   (非稳定, 非适应)
def select_sort(lst):
    for i in range(len(lst)-1):
        k = i
        for j in range(i, len(lst)):
            if lst[j].key < lst[k].key:
                k = j
        if k != i:
            lst[k], lst[i] = lst[i], lst[k]

# 冒泡排序, key() 表示数据的关键码   (稳定, 适应)
def bubble_sort(lst):
    for i in range(len(lst)):
        for j in range(1, len(lst) - i):
            if lst[j-1].key() > lst[j].key():
                lst[j - 1], lst[j] = lst[j], lst[j-1]

# 改进的冒泡排序,当一遍搜索的时候没有发现交换操作,证明此时已经排好序    (稳定, 适应)
def bubble_sort2(lst):
    for i in range(len(lst)):
        found = False
        for j in range(1, len(lst) - i):
            if lst[j-1].key > lst[j].key:
                lst[j-1], lst[j] = lst[j], lst[j-1]
                found = True
        if not found:
            break

# 继续改进的冒泡排序,防止不满足顺序的距离较远的点对排序的影响  (稳定, 适应)
def bubble_sort3(lst):   
    for i in range(len(lst)):
        found = False
        for j in range(1, len(lst)-i):
            if lst[j-1].key > lst[j].key:
                lst[j-1], lst[j] = lst[j], lst[j-1]
                found = True
        if not found:
            break
        for k in range(len(lst)-i-2, 0, -1):
            if lst[k].key < lst[k-1].key:
                lst[k], lst[k-1] = lst[k-1], lst[k]

# 堆排序   O(NlogN)   (非稳定, 非适应)
def heap_sort(elems):
    def siftdown(elems, e, begin, end):
        i, j = begin, begin*2 + 1
        while j < end:
            if j+1 < end and elems[j+1] < elems[j]:
                j += 1
            if e < elems[j]:
                break
            elems[i] = elems[j]
            i, j = j, 2*j+1
        elems[i] = e

    end = len(elems)
    for i in range(end//2, -1, -1):
        siftdown(elems, elems[i], i, end)
    for i in range((end - 1), 0, -1):
        e = elems[i]
        elems[i] = elems[0]
        siftdown(elems, e, 0, i)

# 快速排序   (非稳定,非适应)
def quick_sort(lst):
    def quick_rec(lst, l, r):
        if l >= r:
            return
        i, j = l, r
        pivot = lst[i]
        while(i<j):      # while内部存在两个循环模式为了处理的方向一致
            while (i<j) and (lst[j].key() >= pivot.key()):
                j -= 1
            if (i<j):
                lst[i] = lst[j]
                i += 1
            while (i<j) and (lst[i].key() <= pivot.key()):
                i += 1
            if (i<j):
                lst[j] = lst[i]
                j -= 1
        lst[i] = pivot
        quick_rec(lst, l, i-1)
        quick_rec(lst, i+1, r)
    
    quick_rec(lst, 0, len(lst)-1)

    
# 快速排序的另一种实现   (非稳定, 非适应)
def quick_sort2(lst):
    def qsort(lst, begin, end):
        if begin >= end:
            return 
        pvoit = lst[begin].key
        i = begin
        for j in range(begin+1, end+1):
            if lst[j].key < pvoit:
                i = i+1
                lst[j], lst[i] = lst[i], lst[j]
        lst[i], lst[begin] =lst[begin], lst[i]
        qsort(lst, begin, i-1)
        qsort(lst, i+1, end)
    
    qsort(lst, 0, len(lst)-1)

# 归并排序   (稳定, 非适应)
def merge_sort(lst):
    def merge_pass(lfrom, lto, llen, slen):
        i = 0
        while i + 2*slen < llen:
            merge(lfrom, lto, i, i+slen, i+2*slen)
            i += 2*slen
        if i + slen < llen:     # 剩下两段,诸侯一段小于slen
            merge(lfrom, lto, i, i+slen, llen)
        else:      # 剩下一段,直接对其进行复制
            for j in range(i, llen):
                lto[j] = lfrom[j]

    def merge(lfrom, lto, low, mid, high):
        i, j, k = low, mid, low
        while (i<mid) and (j<high):
            if lfrom[i].key() <= lfrom[j].key():
                lto[k] = lfrom[i]
                i += 1
            else:
                lto[k] = lfrom[j]
                j += 1
            k += 1
        while i < mid:
            lto[k] = lfrom[i]
            i += 1
            k += 1
        while j<high:
            lto[k] = lfrom[j]
            j += 1
            k += 1
    
    slen, llen = 1, len(lst)
    templst = [None]*llen
    while slen < llen:
        merge_pass(lst, templst, slen, llen)
        slen *= 2
        merge_pass(templst, lst, slen, llen)
        slen *= 2

猜你喜欢

转载自blog.csdn.net/weixin_39561100/article/details/81209511