o(nlogn)的排序算法(Python)

快速排序

取一个元素tmp,使元素tmp归位,列表被tmp分为两部分,左边都比tmp小,右边都比tmp大;递归完成排序。

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

def quick_sort(data, left, right):
    if left < right:
        mid = partition(data, left, right)
        quick_sort(data, left, mid - 1)
        quick_sort(data, mid + 1, right)

li = [1,3,5,7,9,2,4,6,8]
quick_sort(li,0, len(li) - 1)
print(li)

堆排序

①建立大根堆
②得到堆顶元素,即为最大元素
③去掉堆顶,将堆最后一个元素放到堆顶,再通过一个调整,重新使堆有序
④此时的堆顶元素为第二大元素
⑤重复步骤③,直至堆为空

def shift(li, root, last):
    i = root
    j = 2 * i + 1   # j是i的左孩子
    tmp = li[root]
    while j <= last:
        if j + 1 <= last and  li[j + 1] > li[j]:
            j = j + 1   # j指向左孩子和右孩子中较大的那一个
        if li[j] > tmp:
            li[i] = li[j]   # 子比父大,较大的数放在根的位置
            i = j; j = 2 * i + 1    # i、j指针向下移动一层
        else:
            li[i] = tmp     # tmp更大,把tmp放在i的位置上
            break
    else: li[i] = tmp   # tmp放到叶子节点上

def heap_sort(li):
    n = len(li)
    for i in range((n - 2) // 2, -1, -1):
        # i表示建堆时调整部分的根的下标,先建小树再建大树
        shift(li, i, n - 1)
    for i in range(n - 1, -1, -1):
        # i指向当前堆的最后一个元素
        li[0], li[i] = li[i],li[0]
        shift(li, 0 ,i - 1)

li = [1,3,5,7,9,2,4,6,8]
heap_sort(li)
print(li)

归并排序

分解:将列表越分越小,直至分成一个元素;
终止条件:一个元素是有序的;
合并:将两个有序列表归并,最终形成一个大列表

def merge(li, left, mid, right):
    i = left; j = mid + 1; t = []
    while i <= mid and j <= right:
        if li[i] <= li[j]:
            t.append(li[i])
            i += 1
        else:
            t.append(li[j])
            j += 1
    while i <= mid:
        t.append(li[i])
        i += 1
    while j <= right:
        t.append(li[j])
        j += 1
    li[left: right + 1] = t

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)

li = [1,3,5,7,9,2,4,6,8]
merge_sort(li, 0, len(li) - 1)
print(li)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值