python 快排与并归排序

本文探讨了两种高级排序算法——快速排序和归并排序。快速排序使用分治策略,通过递归将大问题分解为小问题解决。归并排序同样利用分治,但通过合并有序子数组来实现全局有序。这两种算法都具有对数线性时间复杂度,优于简单的排序算法。
摘要由CSDN通过智能技术生成
  • 算法:解决问题的方法和步骤

  • 评价算法的好坏:渐近时间复杂度(运行时间) 和渐近空间复杂度(运行次数)。

  • 渐近时间复杂度的大O标记:

    • - 常量时间复杂度 - 布隆过滤器 / 哈希存储
    • - 对数时间复杂度 - 折半查找(二分查找)
    • - 线性时间复杂度 - 顺序查找 / 计数排序
    • - 对数线性时间复杂度 - 高级排序算法(归并排序、快速排序)
    • - 平方时间复杂度 - 简单排序算法(选择排序、插入排序、冒泡排序)
    • - 立方时间复杂度 - Floyd算法 / 矩阵乘法运算
    • - 几何级数时间复杂度 - 汉诺塔
    • - 阶乘时间复杂度 - 旅行经销商问题 - NPC

快速排序

运用分治的思想 即将一个复杂问题不断拆解为简单的问题

如图:
在这里插入图片描述
代码示例

 """
 快速排序 - 选择枢轴对元素进行划分,左边都比枢轴小右边都比枢轴大
 """
test_list=[5,8,31,476,7,3,6,94,12,76,48,1,5,7,6,9,5,45878,31,846,0]


def quick_sort(alist,comp= lambda x,y :x<=y):
   alist = alist[:]
   start =0 # 起始位置索引
   end = len(alist)-1 # 结束位置索引
   _quick_sort(alist,start,end,comp)
   return alist

def _quick_sort(alist,start,end,comp):
   if start < end: 
       posvit = _pos(alist,start,end,comp)  
       # 调用闭包让问题无线拆解
       _quick_sort(alist,start,posvit-1,comp)
       _quick_sort(alist,posvit+1,end,comp)
       
def _pos(alist,start,end,comp):
   postvit = alist[end]
   i = start -1
   for j in range(start,end):
       if comp(alist[j],postvit):
           i+=1
           alist[i],alist[j] = alist[j],alist[i]
   alist[i + 1], alist[end] = alist[end], alist[i + 1]  # 调用局部变量 排序
   return i+1

dd=quick_sort(test_list)
dd

out:[0, 1, 3, 5, 5, 5, 6, 6, 7, 7, 8, 9, 12, 31, 31, 48, 76, 94, 476, 846, 45878]

def bubble_sort(items, comp=lambda x, y: x > y):
    """冒泡排序"""
    items = items[:]
    for i in range(len(items) - 1):
        swapped = False
        for j in range(len(items) - 1 - i):
            if comp(items[j], items[j + 1]):
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if not swapped:
            break
    return items
def bubble_sort(items, comp=lambda x, y: x > y):
    """搅拌排序(冒泡排序升级版)"""
    items = items[:]
    for i in range(len(items) - 1):
        swapped = False
        for j in range(len(items) - 1 - i):
            if comp(items[j], items[j + 1]):
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if swapped:
            swapped = False
            for j in range(len(items) - 2 - i, i, -1):
                if comp(items[j - 1], items[j]):
                    items[j], items[j - 1] = items[j - 1], items[j]
                    swapped = True
        if not swapped:
            break
    return items

归并排序

def merge(items1, items2, comp=lambda x, y: x < y):
    """合并(将两个有序的列表合并成一个有序的列表)"""
    items = []
    index1, index2 = 0, 0
    while index1 < len(items1) and index2 < len(items2):
        if comp(items1[index1], items2[index2]):
            items.append(items1[index1])
            index1 += 1
        else:
            items.append(items2[index2])
            index2 += 1
    items += items1[index1:]
    items += items2[index2:]
    return items


def merge_sort(items, comp=lambda x, y: x < y):
    return _merge_sort(list(items), comp)


def _merge_sort(items, comp):
    """归并排序"""
    if len(items) < 2:
        return items
    mid = len(items) // 2
    left = _merge_sort(items[:mid], comp)
    right = _merge_sort(items[mid:], comp)
    return merge(left, right, comp)
def select_sort(items, comp=lambda x, y: x < y):
    """简单选择排序"""
    items = items[:]
    for i in range(len(items) - 1):
        min_index = i
        for j in range(i + 1, len(items)):
            if comp(items[j], items[min_index]):
                min_index = j
        items[i], items[min_index] = items[min_index], items[i]
    return items
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值