python排序算法

一、冒泡排序

冒泡排序的的简单版本

简单选择排序,时间复杂度O(n^2)

ls = [1,2,445,77,43]
length = len(ls)
for i in range(length-1):
    for j in range(i,length-1):
        if ls[j] > ls[j+1]:
            ls[j],ls[j+1] = ls[j+1],ls[j]
print(ls)

升级版,设置flag,当flag不再变化的时候说明后面的序列已经是有序的了,无需再判断。

ls = [1,2,445,77,43]
length = len(ls)
i = 0
flag = True
while i<length-1 and flag:
    flag = False
    for j in range(i,length-1):
        if ls[j] > ls[j+1]:
            ls[j],ls[j+1] = ls[j+1],ls[j]
            flag=True
print(ls)

二、选择排序

class Sqlist():
    def __init__(self, ls):
        self.r = ls

    def select_sort(self):
        ls = self.r
        length = len(self.r)
        for i in range(length - 1):
            min = i
            for j in range(i + 1, length):
                if ls[i] > ls[j]:
                    min = j
            if min != i:
                ls[i], ls[min] = ls[min], ls[i]

 三、直接插入排序

class SQlist():
    def __init__(self,ls):
        self.r = ls
    def insert_sort(self):
        ls=self.r
        length = len(ls)
        for i in range(1,length):
            if ls[i] < ls[i-1]:
                temp = ls[i]
                j = i - 1
                while j>=0 and ls[j]>temp:
                    ls[j+1] = ls[j]
                    j-=1
                ls[j+1] = temp
ls = SQlist([3,1,4,5,2,9,8])
ls.insert_sort()
print(ls.r)

 四、归并排序

def merge(a,b):
    c = []
    h = j = 0
    while j < len(a) and h < len(b):
        if a[j] < b[h]:
            c.append(a[j])
            j += 1
        else:
            c.append(b[h])
            h += 1

    if j == len(a):
        for i in b[h:]:
            c.append(i)
    else:
        for i in a[j:]:
            c.append(i)

    return c
def merge_sort(lists):
    if len(lists) <= 1:
        return lists
    middle = len(lists)//2
    left = merge_sort(lists[:middle])
    right = merge_sort(lists[middle:])
    return merge(left, right)
print(merge_sort([2,12,42,11,6,7,23]))

五、快速排序

思想:选择第一个数作为基准,使用双指针,i,j 分别指向列表开头和结尾,然后j指针先走(一定要尾指针先走!!),找到比基准小的数,然后停下。接着i指针先前走,找到第一个比基准大的数,这时候交换这两个数,交换完j指针继续向前走(再次注意!)。一直重复上述步骤,知道i=j停下,然后交换基准和当前的数。上面操作达到的效果是,基准归位!比基准小的在左边,比基准大的在右边。 递归上述步骤,即可完成排序。

def quicksort(lst, l, r):
    if r - l <= 1:
        return lst
    i, j = l, r
    while i < j:
        if lst[j] >= lst[l]: #j要放在前面
            j -= 1
        elif lst[i] <= lst[l]:
            i += 1
        else:
            lst[i], lst[j] = lst[j], lst[i]
            j -= 1
    lst[l], lst[i] = lst[i], lst[l]
    quicksort(lst, l, i)
    quicksort(lst, i + 1, r)
    return lst

上面步骤可能不直观,可以看看下面这解法,这种解法对快排的本质有很好的阐述。

def quicksort(L):
    if len(L) <= 1:
        return L
    return quicksort([lt for lt in L[1:] if lt <= L[0]]) + L[0:1] + quicksort([lt for lt in L[1:] if lt > L[0]])

注意:上面不是在原来列表的基础上排序,而是生成一个新的列表。如果要在原列表基础上排序。可以用切片赋值回去。不是原地排序空间复杂度高。

交换的核心思想是:保持左边是一个比基准小的序列。右边看成未知的。

import random
from typing import List


def quick_sort(a: List[int]):
    _quick_sort_inner(a, 0, len(a) - 1)


def _quick_sort_inner(a: List[int], low: int, high: int):
    if high <= low:
        return
    m = _partition(a, low, high)
    _quick_sort_inner(a, low, m - 1)
    _quick_sort_inner(a, m + 1, high)


def _partition(a: List[int], low: int, high: int):
    k = random.randint(low, high)
    a[k], a[low] = a[low], a[k]
    pivot, j = a[low], low
    for i in range(low + 1, high + 1):
        if a[i] < pivot:
            j += 1
            a[j], a[i] = a[i], a[j]
    a[low], a[j] = a[j], a[low]
    return j

附:所有排序算法的动态演示:

http://tools.jb51.net/aideddesign/paixu_ys

原文地址:https://www.cnblogs.com/linshuhui/p/9485815.html