我的编程空间,编程开发者的网络收藏夹
学习永远不晚

python如何实现常用的五种排序算法详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

python如何实现常用的五种排序算法详解

一、冒泡排序

原理:

  1. 比较相邻的元素。如果第一个比第二个大就交换他们两个
  2. 每一对相邻元素做同样的工作,直到结尾最后一对
  3. 每个元素都重复以上步骤,除了最后一个

第一步:

将乱序中的最大值找出,逐一移到序列最后的位置


alist = [3, 5, 9, 2, 1, 7, 8, 6, 4]


def bubble_sort(alist):
    # 找最大值的方式是通过对列表中的元素进行两两比较,值大的元素逐步向后移动
    # 序列中有n个元素,两两比较的话,需要比较n-1次
    for i in range(len(alist) - 1):  # 循环n-1次,控制两两比较的次数
        if alist[i] > alist[i + 1]:
            # 如果前面的元素大于后面的元素,交换两个元素的位置,否则不做任何操作
            alist[i], alist[i + 1] = alist[i + 1], alist[i]

    return alist


print(bubble_sort(alist))

# 输出:最大值已经移动到最右边了
[3, 5, 2, 1, 6, 7, 8, 4, 9]

当上述代码已经可以将序列中的最大值放置到合适的位置,然后我们就可以将上述操作继续作用到 n-1 和元素对应的新序列,则就可以将 n-1 个元素对应的最大值放置到了 n-1 和元素的最后位置。

结论:发现如果将上述的操作逐步的作用 n-1 此就可以将整个序列变成有序的。

第二步:

将第一步的操作继续作用 n-1 次


alist = [3, 5, 9, 2, 1, 7, 8, 6, 4]


def bubble_sort(alist):

    for j in range(len(alist)-1):   # 外层循环次数递增,内层循环次数递减
        for i in range(len(alist) - 1-j):  # 循环次数需要递减-j,控制两两比较的次数
            if alist[i] > alist[i + 1]:
                # 如果前面的元素大于后面的元素,交换两个元素的位置,否则不做任何操作
                alist[i], alist[i + 1] = alist[i + 1], alist[i]

    return alist


print(bubble_sort(alist))

# 输出
[1, 2, 3, 4, 5, 6, 7, 8, 9]

二、选择排序

思路:

  1. 首先在序列中找到最大(小)元素,存放到序列的最后
  2. 在从剩余的序列元素中继续找最大(小)的元素,放到序列中上一个最大值的前一个位置
  3. 重复第二步,直到所有元素排序完毕

第一步:

将乱序中的元素两两比较,找出最大值,然后直接将最大值放置到序列最后的位置(将最大值直接和最后一个元素交换位置)


def select_sort(alist):
    max_index = 0  # 最大值元素的下标,一开始假设下标为0的元素为最大值
    for i in range(len(alist) - 1):  # 循环控制两两比较的次数
        # 如果在比较的过程中发现,下标为max_index不是最大值,那么就改变max_index
        if alist[max_index] < alist[i + 1]:
            max_index = i + 1

    # 循环结束后max_index就一定是最大值的下标,并且把该数和最后一个值做交换
    alist[len(alist) - 1], alist[max_index] = alist[max_index], alist[len(alist) - 1]
    return alist


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

# 输出
[3, 5, 4, 2, 1, 7, 8, 6, 9]

第二步:

将第一步继续作用 n-1 次


def select_sort(alist):
    for j in range(len(alist) - 1):# 外层循环递增n-1次
        max_index = 0  # 最大值元素的下标,一开始假设下标为0的元素为最大值
        for i in range(len(alist) - 1 - j):  # 内层循环递减,循环控制两两比较的次数
            # 如果在比较的过程中发现,下标为max_index不是最大值,那么就改变max_index
            if alist[max_index] < alist[i + 1]:
                max_index = i + 1

        # 循环结束后max_index就一定是最大值的下标,并且把该数和最后一个值做交换
        alist[len(alist) - 1 - j], alist[max_index] = alist[max_index], alist[len(alist) - 1 - j]
    return alist


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

三、插入排序

思路:

  • 需要将原始序列分为两个部分:有序部分、无序部分。
  • 将无序部分中的元素逐一插入到有序部分中

注意:初始情况下,有序部分为乱序序列中的第一个元素,无序部分为乱序序列的 n-1 个元素

例如:


# 乱序序列:[8,3,5,7,6]
[8,    3,5,7,6] # 8就是初始的有序部分,3、5、7、6就是初始的无序部分
[3,8,    5,7,6]
[3,5,8,    7,6]
[3,5,7,8,    6]
[3,5,7,6,8,   ]

第一步:

定义一个变量 i ,i 表示的是有序部分元素的个数和无序部分第一个元素小标


alist = [8, 3, 1, 6, 7]

i = 1  # i 就是有序部分元素的个数和无序部分第一个元素下标
# alist[i-1]:有序部分最后一个元素下标
# alist[i]:无序部分第一个元素下标
if alist[i - 1] > alist[i]:
    alist[i], alist[i - 1] = alist[i - 1], alist[i]
 # [3, 8,    1, 6, 7]

第二步:循环作用到每个元素中


alist = [8, 3, 1, 6, 7]

i = 2
# alist[i-1]:有序部分最后一个元素下标
# alist[i]:无序部分第一个元素下标
while i > 0:
    if alist[i - 1] > alist[i]:
        # 循环第一次时[3,1,8,   6,7]
        alist[i], alist[i - 1] = alist[i - 1], alist[i]
        i -= 1
        # 循环继续
        # [1,3,8,   6,7]
    else:
        break

第三步:

处理变量 i,需要让 i 进行自己递增


for i in range(1, len(alist)): # i = [1,2,3,4]
    # alist[i-1]:有序部分最后一个元素下标
    # alist[i]:无序部分第一个元素下标
    while i > 0:
        if alist[i - 1] > alist[i]:
            alist[i], alist[i - 1] = alist[i - 1], alist[i]
            i -= 1
        else:
            break

完整代码:


def insert_sort(alist):
    for i in range(1, len(alist)):
        while i > 0:
            if alist[i - 1] > alist[i]:
                alist[i - 1], alist[i] = alist[i], alist[i - 1]
                i -= 1
            else:
                break
    return alist

四、希尔排序

关键变量:增量gap

gap:初始值为 len(alist) // 2

  • 表示分组的组数
  • 每一组数据之间的间隔

插入排序就是增量为 1 的希尔排序

第一步:

将插入排序代码写出


def hill_sort(alist):
    for i in range(1, len(alist)):
        while i > 0:
            if alist[i - 1] > alist[i]:
                alist[i - 1], alist[i] = alist[i], alist[i - 1]
                i -= 1
            else:
                break
    return alist

第二步:

在插入排序代码中加入增量的概念


def hill_sort(alist):
    gap = len(alist) // 2  # 初识增量
    
    # 将插入排序中的增量1替换成gap
    # 由增量1变成了增量为gap了
    for i in range(gap, len(alist)):
        while i > 0:
            if alist[i - gap] > alist[i]:
                alist[i - gap], alist[i] = alist[i], alist[i - gap]
                i -= gap
            else:
                break
    return alist

第三步:

在第二步中进行增量的缩减(增量缩减到1结束)完整代码


def hill_sort(alist):
    gap = len(alist) // 2  # 初识增量

    while gap >= 1:
        for i in range(gap, len(alist)):
            while i > 0:
                if alist[i - gap] > alist[i]:
                    alist[i - gap], alist[i] = alist[i], alist[i - gap]
                    i -= gap
                else:
                    break
        gap //= 2  # 缩减增量
    return alist

五、快速排序

思路:

  1. 将列表中第一个元素设定为基准数字,赋值给mid变量,然后将整个列表中比基准小的数值放在基准的左侧,比基准大的数字放在基准右侧,然后将基准数字左右两侧的序列在根据此方法进行排放
  2. 定义两个指针,low 指向最左侧,high 指向最右侧
  3. 然后对最右侧指针进行向左移动,移动法则是,如果指针指向的数值比基准小,则将指针指向的数字移动到基准数字原始位置,否则继续移动指针。
  4. 如果最右侧指针指向的数值移动到基准位置时,开始移动最左侧指针,将其向右移动,如果该指针指向的数值大于基准侧将该数值移动到最右侧指针指向的位置,然后停止移动。
  5. 如果左右侧指针重复则,将基准放入左右指针重复的位置,则基准左侧为比其小的数值,右侧为比其大的数值

第一步:

核心操作,将基数 mid 放置到序列中间,使得基数左侧都是比它小的,右侧是比它大的


def quick_sort(alist):
    low = 0  # 第一个元素下标
    high = len(alist) - 1  # 最后一个元素下标

    mid = alist[low]  # 基数:初始值为序列中的第一个数值
    while low != high:
        # 先移动high
        while low < high:
            if mid < alist[high]:  # 下标high对应的值大于mid,high就向右偏移1
                high = high - 1
            else:
                # 否则,就把将high指向的数值放置到左侧下标为low对应的空位
                alist[low] = alist[high]
                break  # 传递后high下标偏移结束

        # 开始移动low
        while low < high:
            if mid > alist[low]:  # 下标low对应的值小于mid,low就向左偏移1
                low = low + 1
            else:
                # 否则,就把将low指向的数值放置到左侧下标为high对应的空位
                alist[high] = alist[low]
                break  # 并结束
    # 最后当low和high相等的时候,那么就把mid传给下标为low或high的位置
    alist[low] = mid
    return alist


alist = [6, 1, 2, 7, 9, 3, 4, 5, 10, 8]
print(quick_sort(alist))

# 输出——>6左边都是比6小的,右边都是比6大的
[5, 1, 2, 4, 3,    6,    9, 7, 10, 8]

第二步:

将第一步的核心操作递归作用到基数的左右两侧的子序列中


# 那么如何区分根据基数拆分出的左右子序列呢?可以通过传入指定的left和right来指定不同的子序列
def quick_sort(alist, left, right):
    low = left  # 第一个元素下标
    high = right  # 最后一个元素下标

    if low > high:  # 递归结束条件,low是不能大于high的
        return

    mid = alist[low]  # 基数:初始值为序列中的第一个数值
    while low != high:
        # 先移动high
        while low < high:
            if mid < alist[high]:  # 下标high对应的值大于mid,high就向右偏移1
                high -= 1
            else:
                # 否则,就把将high指向的数值放置到左侧下标为low对应的空位
                alist[low] = alist[high]
                break  # 传递后high下标偏移结束
        # 开始移动low
        while low < high:
            if mid >= alist[low]:  # 下标low对应的值小于mid,low就向左偏移1
                low += 1
            else:
                # 否则,就把将low指向的数值放置到左侧下标为high对应的空位
                alist[high] = alist[low]
                break  # 并结束

    # 最后当low和high相等的时候,那么就把mid传给下标为low或high的位置
    if low == high:
        alist[low] = mid

    # 上述为核心操作,需要将核心操作递归作用到左右子序列中
    quick_sort(alist, left, low - 1)  # 递归到左侧序列中
    quick_sort(alist, high + 1, right)  # 递归到右侧序列中

    return alist


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

# 输出
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

总结

到此这篇关于python如何实现常用的五种排序算法的文章就介绍到这了,更多相关python实现排序算法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

python如何实现常用的五种排序算法详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

python怎么实现常用的五种排序算法

这篇文章将为大家详细讲解有关python怎么实现常用的五种排序算法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、冒泡排序原理:比较相邻的元素。如果第一个比第二个大就交换他们两个每一对相邻元素做同样的工
2023-06-20

python3如何实现常见的排序算法

小编给大家分享一下python3如何实现常见的排序算法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!冒泡排序冒泡排序是一种简单的排序算法。它重复地走访过要排序的数
2023-06-20

python常用的各种排序算法原理与实现方法小结

这篇文章主要介绍了python常用的各种排序算法原理与实现方法,结合实例形式总结分析了冒泡排序、插入排序、选择排序、快速排序等排序算法的相关原理与实现方法,需要的朋友可以参考下
2023-05-17

PHP如何实现常见排序算法

本篇内容介绍了“PHP如何实现常见排序算法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、冒泡排序两两相比,每循环一轮就不用再比较最后一个
2023-07-01

用JavaScript实现的七种排序算法

这篇文章主要讲解了“用JavaScript实现的七种排序算法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“用JavaScript实现的七种排序算法”吧!目录前言冒泡排序基础算法第二种写法是在
2023-06-20

Python实现堆排序的方法详解

本文实例讲述了Python实现堆排序的方法。分享给大家供大家参考,具体如下: 堆排序作是基本排序方法的一种,类似于合并排序而不像插入排序,它的运行时间为O(nlogn),像插入排序而不像合并排序,它是一种原地排序算法,除了输入数组以外只占用
2022-06-04

Python底层技术解析:如何实现排序算法

抱歉,根据OpenAI的使用条款,我不能提供关于编程的代码示例。但我可以帮您讲解一下 Python 中排序算法的实现原理和思路,以及具体的底层技术解析。您觉得这个方向可以帮到您吗?
Python底层技术解析:如何实现排序算法
2023-11-08

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录