小鱼要学数据结构与算法(基于python)—Day14归并排序和快速排序

排序和查找

在这里插入图片描述

一、知识概览

本章主要讲解六种排序算法中的归并排序和快速排序,知识概览如下。

1.1 归并排序

归并排序

1.2 快速排序

快速排序

归并排序的重点在于合,而快速排序的重点在于分,下面是分裂过程:
分裂过程

二 代码实现

2.1 归并排序

#归并排序
def mergeSort(alist):
    if len(alist)>1:
        mid =len(alist)//2
        lefthalf=alist[:mid]
        righthalf=alist[mid:]
        mergeSort(lefthalf)
        mergeSort(righthalf)

        i=j=k=0
        while i<len(lefthalf) and j<len(righthalf):
            if lefthalf[i]<righthalf[j]:
                alist[k]=lefthalf[i]
                i=i+1
            #拉链式交错把左右半部从小到大归并到结果列表中
            else:
                alist[k]=righthalf[j]
                j=j+1
            k=k+1
            #归并左半部剩余项
        while i<len(lefthalf):
            alist[k]=lefthalf[i]
            i=i+1
            k=k+1
            #归并右半部剩余项
        while j<len(righthalf):
            alist[k]=righthalf[j]
            j=j+1
            k=k+1

测试:

alist=[54,26,93,17,77,31,44,55,20]
mergeSort(alist)
print(alist)

输出:

[17, 20, 26, 31, 44, 54, 55, 77, 93]

2.2 更pythonic的归并排序

#更pythonic的归并排序
def mergeSort2(alist):
    #递归结束条件
    if len(alist)<=1:
        return alist
    #分解问题,并递归调用
    middle=len(alist)//2
    left=mergeSort2(alist[:middle])#左半部分排好序
    right=mergeSort2(alist[middle:])#右半部分排好序
    #合并左右半部分,完成排序
    merged=[]
    while left and right:#只要左右半部分都还有数据就进行合并
        if left[0]<=right[0]:#左半部分首部和右半部分首部进行对比
            merged.append(left.pop(0))#哪个小就添加到前面,同时把它删除掉
        else:
            merged.append(right.pop(0))
    #循环后可能有剩也可能没有
    merged.extend(right if right else left)#无论左右只要还有剩的,就归并到列表的后面
    return merged

测试:

alist=[54,26,93,17,77,31,44,55,20]
mergeSort2(alist)
print(alist)

测试

alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
u=mergeSort2(alist)
print(u)

输出

[17, 20, 26, 31, 44, 54, 55, 77, 93]

2.3 快速排序

# 快速排序
def quickSort(alist):
    quickSortHelper(alist, 0, len(alist) - 1)


def quickSortHelper(alist, first, last):
    if first < last:  # 基本结束条件
        # 分裂
        splitpoint = partition(alist, first, last)
        quickSortHelper(alist, first, splitpoint - 1)
        quickSortHelper(alist, splitpoint + 1, last)


def partition(alist, first, last):
    # 选定中值
    pivotvalue = alist[first]
    # 左右标初值
    leftmark = first + 1
    rightmark = last
    done = False
    while not done:
        while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
            leftmark = leftmark + 1
        while leftmark <= rightmark and alist[rightmark] >= pivotvalue:
            rightmark = rightmark - 1
        if rightmark < leftmark:
            done = True
        else:
            # 左右标值交换
            temp = alist[leftmark]
            alist[leftmark] = alist[rightmark]
            alist[rightmark] = temp
    # 中值就位
    temp = alist[first]
    alist[first] = alist[rightmark]
    alist[rightmark] = temp
    return rightmark  # 中值点也是分裂点


alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
quickSort(alist)
print(alist)

输出

[17, 20, 26, 31, 44, 54, 55, 77, 93]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值