排序算法总结

时间空间复杂度

1直接选择排序 

2堆排序

3插入排序

4冒泡排序

5快速排序(分治

6归并排序

7基数排序


时间空间复杂度

1直接选择排序 

        def select_sort(lst):
            if lst == []: return []
            for i in range(len(lst)-1): #i不断增加序号
                smallest = i
                for j in range(i, len(lst)):
                    if lst[j] < lst[smallest]:#选择最小的,放到和第一个交换
                        smallest = j
                lst[i], lst[smallest] = lst[smallest], lst[i]
            return lst

2堆排序

堆排序详细图解(通俗易懂)_Oorik的博客-CSDN博客

升序:小根堆

1从最后一个非叶子结点开始(第一个非叶子结点 arr.length/2-1),判断其和叶子节点大小,最大的放到根节点,小的放到叶子节点--还要考虑此叶子节点为根的子树是否仍满足条件

2步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

#重构大根堆+交换
def adjustHeap(lst, begin, end):
    if lst == []: return []
    temp=begin
    i, j = begin, begin * 2 + 1  #根节点要最大,左节点开始向下找
    while j < end:
        if j + 1 < end and lst[j + 1] > lst[j]:  
            j += 1   #j等于左节点开始下面更大的叶子节点
        elif temp > lst[j]:  break #比下面最大的都大,结束循环
        else: 
            lst[i] = lst[j]  #交换,i拿到更大的
            lst[j] = temp
            i, j = j, 2 * j + 1  #改变后继续建

def heap_sort(lst):
    if lst == []: return []
    for i in range((len(lst)// 2) - 1, -1, -1):#从最后一个非叶子结点开始len/2-1
        adjustHeap(lst,  i, len(lst))
    for i in range(end - 1, 0, -1):#结构混乱重新调整
        lst[i],lst[0] = lst[0],lst[i]
        adjustHeap(lst, 0, i)
    return lst



#或者递归
def adjust_heap(lists, i, size):
    # 调整堆
    lchild = 2 * i + 1
    rchild = 2 * i + 2
    maxi = i
    if lchild < size and lists[maxi] < lists[lchild]:
        maxi = lchild
    if rchild < size and lists[maxi] < lists[rchild]:
        maxi = rchild
    if maxi != i:
        # 如果做了堆调整,maxi的值等于左/右节点的,对调操作
        lists[maxi], lists[i] = lists[i], lists[maxi]
        adjust_heap(lists, maxi, size)

3插入排序

无序变成一个有序,每次拿出一个数字插入到新的有序中

第i趟排序时,有序数组中的数字就有i个,就需要进行i次比较,因此循环i次

        def Insert_sort(lst):#升序
            if lst == []: return []
            for i in range(1, len(lst)):
                temp = lst[i]  #要插入的数
                j = i #插入位置,向左找序列位置并移动
                while j > 0 and temp < lst[j - 1]: #要插入的数更小
                    lst[j] = lst[j - 1] #不停向右移动
                    j -= 1
                lst[j] = temp #插入
            return lst

4冒泡排序

n轮每次把最大的移到最后,

最好情况:加入标记swaptrue,如果循环没有进行交换,可以理解为数组已经排好序,一轮后就可以退出排序;

        def bubble_sort(lst):
            if lst == []: return []
            swaptrue=False
            for i in range(len(lst)):
                for j in range(1, len(lst) - i):
                    if lst[j - 1] > lst[j]:
                        lst[j - 1], lst[j] = lst[j], lst[j - 1]
                        swaptrue=True
                if didSwap == false:return
            return lst

5快速排序(分治

把基准数大的都放在基准数的右边,把比基准数小的放在基准数的左边

图解:快速排序---(面试碰到过好几次)_nrsc的博客-CSDN博客

时间复杂度:快速排序 及其时间复杂度和空间复杂度_寒夕若梦的博客-CSDN博客

时间复杂度公式为:T[n] = 2T[n/2] +n;T[n/2]为平分后的子数组的时间复杂度,f[n] 为平分这个数组时所花的时间遍历一遍;

最优的情况就是每一次取到的元素都刚好平分整个数组:T[n] = n + nlogn  

最差的情况就是每一次取到的元素就是数组中最小/最大的,这种情况其实就是冒泡排序了(每一次都排好一个元素的顺序)

快速排序,分治法策略來把一個序列分為较小和较大的2个子序列,然后递归地排序两个子序列。

def quick_sort(lst):
    if not lst: return []
    pivot = lst[0]
    left = quick_sort([x for x in lst[1: ] if x < pivot])
    right = quick_sort([x for x in lst[1: ] if x >= pivot])
    return left + [pivot] + right

##2

def quick_sort(li, start, end):
    # start=end ,证明要处理的数据只有一个> ,证明右边没有数据
    if start >= end:
        return
    # 定义两个游标,分别指向0和末尾位置
    left = start
    right = end
    mid = li[left] # 把0位置的数据,认为是中间值
    while left < right:
        while left < right and li[right] >= mid:
            right -= 1
        li[left] = li[right]
        while left < right and li[left] < mid:
            left += 1
        li[right] = li[left]
    
    li[left] = mid    # while结束后,把mid放到中间位置,left=right
    quick_sort(li, start, left-1)# 递归处理左边的数据
    quick_sort(li, left+1, end)  # 递归处理右边的数据

6归并排序

将两个顺序序列合并成一个顺序序列的方法:2个合并--4个合并--。。。各自有序再合并有序

        def merge_sort(lst):
            if len(lst) <= 1: return lst
            mid = len(lst) // 2

            left = merge_sort(lst[: mid])
            right = merge_sort(lst[mid:])
            return merge(left, right)
        def merge(left, right):
            l, r, res = 0, 0, [] #申请空间,大小为两个已经排序序列之和,该空间用来存放合并后的序列
            while l < len(left) and r < len(right):
                if left[l] <= right[r]:
                    res.append(left[l])
                    l += 1
                else:
                    res.append(right[r])
                    r += 1
            res += left[l:]
            res += right[r:]
            return res

7基数排序

基数排序-----python(简单易懂)_瑶子ove的博客-CSDN博客
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中,将数值重新串接,再根据十位数。持续进行以上的动作直至最高位数为止。

def RadixSort(a):
    i = 0                                             #初始为个位排序
    n = 1                                           #最小的位数置为1(包含0)
    max_num = max(a)                       #得到带排序数组中最大数
    while max_num > 10**n:              #得到最大数是几位数
        n += 1
    while i < n:
        bucket = {}                             #用字典构建桶
        for x in range(10):
            bucket.setdefault(x, [])    #将每个桶置空
        for x in a:                               #对每一位进行排序
            radix =int((x / (10**i)) % 10)   #得到每位的基数
            bucket[radix].append(x) #将对应的数组元素加入到相应位基数的桶中
        j = 0
        for k in range(10):
            if len(bucket[k]) != 0:       #若桶不为空
                for y in bucket[k]:         #将该桶中每个元素
                    a[j] = y                       #放回到数组中
                    j += 1
        i += 1

计数排序,桶排序,基数排序

参考:【Kick Algorithm】十大排序算法及其Python实现

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值