排序算法汇总

排序算法

一、时间复杂度为O(n^2)的排序算法

1、选择排序
def select_sort(li):
    for i in range(len(li) - 1):
        min_loc = i
        for j in range(i, len(li) - 1):
            if li[j] < li[min_loc]:
                min_loc = j`
        if min_loc != i:
            li[i], li[min_loc] = li[min_loc], li[i]
    return li
2、冒泡排序
def bubble_sort(li):
    for i in range(len(li) - 1):
        for j in range(len(li) - 1 - i):
            if li[j] > li[j + 1]:
                li[j], li[j + 1] = li[j + 1], li[j]
    return li
3、插入排序
def insert_sort(li):
    for i in range(1, len(li)):
        j = i - 1  # 代表有序区数的下标
        tmp = li[i]  # 出来的数
        while j >= 0 and tmp < li[j]:
            li[j + 1] = li[j]
            j -= 1
        li[j + 1] = tmp
    return li

二、时间复杂度为O(nlogn)的排序算法

1、快排

①选出一个临时的数,使得在该数左边的都比它小,右边的都比它大

②两个指针,一个向左走一个向右走,条件是left<right

③在该数右边找到比他小的数放到左边;在该数左边找到比它大的数放到右边(while循环)

④循环结束之后在这个数左边的数都小于它,右边的数都大于它

⑤最后找到mid,left-mid递归,mid+1,right递归

def partition(li, left, right):
    tmp = li[left]
    while left < right:
        while left < right and tmp <= li[right]:
            right -= 1
        li[left] = li[right]
        while left < right and tmp >= li[left]:
            left += 1
        li[right] = li[left]
    li[left] = tmp
    return left


def quick_sort(li, left, right):
    if left < right:
        mid = partition(li, left, right)
        quick_sort(li, 0, mid)
        quick_sort(li, mid + 1, right)
    return li
2、归并

①首先merge函数将数组分为left-mid,以及mid+1-right的部分

②建立一个新的列表,两个指针分别对上面两部分进行拆分

③比较li【i】和li【j】 更小的部分,加入到列表中

④如果左右两部分的长度不一致,总会有一边被先加到临时列表中,最后在把没有比较完的元素加入临时列表

⑤先定义mid,递归左边,递归右边,左右两边合并

def merge(li, left, mid, right):
    i = left
    j = mid + 1
    ltmp = []
    while i <= mid and j <= right:
        if li[i] < li[j]:
            ltmp.append(li[i])
            i += 1
        else:
            ltmp.append(li[j])
            j += 1
    while i <= mid:
        ltmp.append(li[i])
        i += 1
    while j <= right:
        ltmp.append(li[j])
        j += 1
    li[left:right+1]=ltmp # 写回到原列表中


def merge_sort(li, left, right):
    if left < right:
        mid = (left + right) // 2
        merge_sort(li, left, mid)
        merge_sort(li, mid + 1, right)
        merge(li, left, mid, right)
3、堆排序
def sift(li, low, high):
    i = low
    j = 2 * i + 1
    tmp = li[low]
    while j <= high:
        if j + 1 <= high and li[j] < li[j + 1]:
            j += 1
        if li[j] > tmp:
            li[i] = li[j]
            i = j
            j = 2 * i + 1
        else:
            li[i] = tmp
            break
    else:
        li[i] = tmp

def dui_sort(li):
    n = len(li)
    # 建堆----大根堆(父节点大于每一个孩子节点)
    for i in range((n - 2) // 2, -1, -1):
        sift(li, i, n - 1) # 建堆时自底向顶
    for i in range(n - 1, -1, -1):
        li[0], li[i] = li[i], li[0]
        sift(li, 0, i-1) # 出数时的调整自顶向下
    return li
4、堆排序实现前topK的问题

维护一个k大小的大根堆,建堆-和剩下的元素比较-出数

def sift(li, low, high):
    i = low
    j = 2 * i + 1
    tmp = li[low]
    while j <= high:
        if j + 1 <= high and li[j] > li[j + 1]:
            j += 1
        if li[j] < tmp:
            li[i] = li[j]
            i = j
            j = 2 * i + 1
        else:
            li[i] = tmp
            break
    else:
        li[i] = tmp
        
def topK(li, k):
    heap = li[:k]
    # 建堆---小根堆
    for i in range((k - 1) // 2, -1, -1)
        sift(heap, i, k - 1)
    for num in li[k:]:
        if num > heap[0]:  # heap[0]是大数里最小的数
            heap[0] = num
            sift(heap, 0, k - 1)
    # 出数
    for i in range(k - 1, -1, -1):
        heap[0], heap[i] = heap[i], heap[0]
        sift(heap, 0, i - 1)
    return heap
5、桶排序

注释: 分桶----在桶内排序,因为使用appen,每次进来一个元素就和前面的元素比较一次,遇到比它小的数就停掉

def bucket_sort(li,n=10,max_num=1000):
    bucket = [[] for i in range(n)]
    for num in li:
        i = min(num // (max_num // n), n-1)
        bucket[i].append(num)
        # 一边插入一边排序,所以是从最后一个和前面的比较,遇到比它小的数就结束
        for j in range(len(bucket[i])-1,0,-1):
            if bucket[i][j] < bucket[i][j-1]:
                bucket[i][j],bucket[i][j-1] = bucket[i][j-1],bucket[i][j]
            else:
                break
    buc = []
    for val in bucket:
        buc.extend(val)
    return buc
6、基数排序
def radix_sort(li):
    max_num = max(li)
    it = 0
    while 10 ** it <= max_num:
        bucket = [[] for _ in range(10)] # 建桶必须写循环里边,每次循环桶会被清空
        for num in li:
            i = (num // 10 ** it) % 10
            bucket[i].append(num)
        li.clear()
        for j in bucket:
            li.extend(j)
        it += 1
    return li
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值