百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Python 实现七大排序算法 python的排序

off999 2024-12-26 15:53 33 浏览 0 评论


技术博客: https://github.com/yongxinz/tech-blog

同时,也欢迎关注我的微信公众号 AlwaysBeta,更多精彩内容等你来。

本文用 Python 实现了插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序。

先整体看一下各个算法之间的对比,然后再进行详细介绍:

排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 排序方式 稳定性

插入排序 O(n2) O(n) O(n2) O(1) In-place 稳定

冒泡排序 O(n2) O(n) O(n2) O(1) In-place 稳定

选择排序 O(n2) O(n2) O(n2) O(1) In-place 不稳定

快速排序 O(n log n) O(n log n) O(n2) O(log n) In-place 不稳定

希尔排序 O(n log n) O(n log n) O(n log n) O(1) In-place 不稳定

堆排序 O(n log n) O(n log n) O(n log n) O(1) In-place 不稳定

归并排序 O(n log n) O(n log n) O(n log n) O(n) Out-place 稳定

n:数据规模

In-place:占用常数内存,不占用额外内存

Out-place:占用额外内存

稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同

插入排序

描述

时间复杂度为 O(n^2),是稳定的排序方法。

插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序。

插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。

代码实现

# -*- coding: UTF-8 -*-


def insert_sort(lists):
    # 插入排序 时间复杂度为 O(n^2)
    count = len(lists)
    for i in range(1, count):
        key = lists[i]
        j = i - 1
        while j >= 0:
            if lists[j] > key:
                lists[j + 1] = lists[j]
                lists[j] = key
            j -= 1
    return lists


if __name__ == "__main__":
    test = [2, 5, 4, 6, 7, 3, 2]
    print(insert_sort(test))

希尔排序

描述

时间复杂度为 O(n log n),是不稳定的排序方法。

希尔排序(Shell Sort)是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。

该方法因 DL.Shell 于 1959 年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。

代码实现

# -*- coding: UTF-8 -*-


def shell_sort(lists):
    # 希尔排序 时间复杂度是 O(n log n)
    count = len(lists)
    step = 2
    group = int(count / step)
    while group > 0:
        for i in range(0, group):
            j = i + group
            while j < count:
                k = j - group
                key = lists[j]
                while k >= 0:
                    if lists[k] > key:
                        lists[k + group] = lists[k]
                        lists[k] = key
                    k -= group
                j += group
        group = int(group / step)
    return lists


if __name__ == "__main__":
    test = [2, 5, 4, 6, 7, 3, 2]
    print(shell_sort(test))

冒泡排序

描述

时间复杂度是 O(n2), 是稳定排序算法。

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

代码实现

# -*- coding: UTF-8 -*-


def bubble_sort(lists):
    # 冒泡排序 时间复杂度是 O(n2)
    count = len(lists)
    for i in range(0, count - 1):
        for j in range(0, count - i - 1):
            if lists[j] > lists[j + 1]:
                lists[j], lists[j + 1] = lists[j + 1], lists[j]
    return lists


if __name__ == "__main__":
    test = [2, 5, 4, 6, 7, 3, 2]
    print(bubble_sort(test))

快速排序

描述

快速排序的时间复杂度是 O(n log n), 是不稳定排序算法。

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

代码实现

# -*- coding: UTF-8 -*-


def quick_sort(lists, left, right):
    # 快速排序 时间复杂度是 O(n log n)
    if left >= right:
        return lists
    key = lists[left]
    low = left
    high = right
    while left < right:
        while left < right and lists[right] >= key:
            right -= 1
        lists[left] = lists[right]
        while left < right and lists[left] <= key:
            left += 1
        lists[right] = lists[left]
    lists[right] = key
    quick_sort(lists, low, left - 1)
    quick_sort(lists, left + 1, high)
    return lists


if __name__ == "__main__":
    test = [2, 5, 4, 6, 7, 3, 2]
    print(quick_sort(test, 0, len(test) - 1))

直接选择排序

描述

选择排序的时间复杂度是 O(n2), 是不稳定排序算法。

基本思想:第 1 趟,在待排序记录 r1 ~ r[n] 中选出最小的记录,将它与 r1 交换;第 2 趟,在待排序记录 r2 ~ r[n] 中选出最小的记录,将它与 r2 交换;以此类推,第 i 趟在待排序记录 r[i] ~ r[n] 中选出最小的记录,将它与 r[i] 交换,使有序序列不断增长直到全部排序完毕。

代码实现

# -*- coding: UTF-8 -*-


def select_sort(lists):
    # 选择排序 时间复杂度是 O(n2)
    count = len(lists)
    for i in range(0, count):
        min = i
        for j in range(i + 1, count):
            if lists[min] > lists[j]:
                min = j
        lists[min], lists[i] = lists[i], lists[min]
    return lists


if __name__ == "__main__":
    test = [2, 5, 4, 6, 7, 3, 2]
    print(select_sort(test))

堆排序

描述

堆排序的时间复杂度是 O(n log n), 是不稳定排序算法。

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即 A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

代码实现

# -*- coding: UTF-8 -*-

from collections import deque


def swap_param(lists, i, j):
    lists[i], lists[j] = lists[j], lists[i]
    return lists


def heap_adjust(lists, start, end):
    temp = lists[start]

    i = start
    j = 2 * i

    while j <= end:
        if (j < end) and (lists[j] < lists[j + 1]):
            j += 1
        if temp < lists[j]:
            lists[i] = lists[j]
            i = j
            j = 2 * i
        else:
            break
    lists[i] = temp


def heap_sort(lists):
    length = len(lists) - 1

    first_sort_count = length / 2
    for i in range(first_sort_count):
        heap_adjust(lists, first_sort_count - i, length)

    for i in range(length - 1):
        lists = swap_param(lists, 1, length - i)
        heap_adjust(lists, 1, length - i - 1)

    return [lists[i] for i in range(1, len(lists))]


def main():
    lists = deque([50, 16, 30, 10, 60,  90,  2, 80, 70])
    lists.appendleft(0)
    print heap_sort(lists)


if __name__ == '__main__':
    main()

归并排序

描述

时间复杂度是 O(n log n), 是稳定排序算法。

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

代码实现

# -*- coding: UTF-8 -*-


def merge_sort(lists):
    # 归并排序 时间复杂度是 O(n log n)
    if len(lists) <= 1:
        return lists

    num = int(len(lists) / 2)
    left_lists = merge_sort(lists[:num])
    right_lists = merge_sort(lists[num:])

    return merge(left_lists, right_lists)


def merge(left_lists, right_lists):
    left, right = 0, 0
    result = []

    while left < len(left_lists) and right < len(right_lists):
        if left_lists[left] < right_lists[right]:
            result.append(left_lists[left])
            left += 1
        else:
            result.append(right_lists[right])
            right += 1

    result += left_lists[left:]
    result += right_lists[right:]

    return result


if __name__ == "__main__":
    test = [2, 5, 4, 6, 7, 3, 2]
    print(merge_sort(test))

参考文档:

https://baagee.vip/index/article/id/101.html

https://www.jianshu.com/p/d174f1862601

相关推荐

怎么开启路由器wifi(怎么开启路由器的dhcp功能)

把路由器改为开放网络方法如下:1、打开浏览器,在地址栏输入路由器网关IP地址(路由器背后的标签上有,一般是192.168.1.1),输入登录用户名和密码(一般均为admin);2、登录成功后就显示运行...

win10加载不出来桌面黑屏(window10加载不出来)

方法一、如果是遇到了突发性黑屏首先尝试使用Ctrl+Alt+Delete组合键来进行电脑重启一般重启可以解决大部分黑屏故障。win10电脑黑屏按什么键恢复_win10电脑黑屏一键恢复的方法方法...

怎么用火绒关闭win安全中心(win10火绒安全软件怎么关闭)

一、火绒防火墙关闭方法在电脑上运行火绒软件后,点击首页界面的“防护中心”,在病毒防护界面可以关闭文件、U盘、邮件等保护功能,。系统防护:在该界面可以关闭系统防护功能,。网络防护:可以关闭网络保护等功...

微软应用商店下载手机版(微软应用商店在哪下)

、在桌面任务栏找到微软应用商店,点击并打开。2、进入页面后点击【应用】,进入应用页面。3、在页面里往下移动,找到热门应用,找到一个软件,点击进入。4、进入页面后,点击【安装】,软件会自动安装,安装完毕...

win11系统怎么查看电脑配置(win11怎么查看系统版本)

答:win11查看电脑配置步骤如下。1.点击下方任务栏的windows图标或者按下键盘“windows键”打开开始菜单。2.在开始菜单中找到“设置”或“settings”,一般是右上角的齿轮状按钮,3...

麦克风没坏但是没声音(麦克风没声怎么回事)

几种可能性,供您参考:1、麦是完全好的(其它机子上可以用)2、插孔没有插错3、音量控制里的麦克风并没有静音掉4、声卡驱动已重装过N次,新的旧的都试过了5、音量控制→属性→录音→麦克风下面的勾...

win10系统怎么分区(win10应该怎么分区)
  • win10系统怎么分区(win10应该怎么分区)
  • win10系统怎么分区(win10应该怎么分区)
  • win10系统怎么分区(win10应该怎么分区)
  • win10系统怎么分区(win10应该怎么分区)
wps office是干什么的(wps office是干什么的可以卸载吗)

   WPSOffice一站式办公服务平台,具有可兼容Word、Excel、PPT三大办公组件的不同格式,支持PDF文档的编辑与格式转换集成思维导图、流程图等诸多功...

百度网页(百度网页自动翻译怎么设置)

1、百度的新闻源网站太多了,基本上大型的商业门户+政府官方的媒体、机构部门都是。2、出现在【百度新闻】里的网站都是新闻源网站。3、怎么判断一个网站是不是新闻源:1)在百度新闻下直接搜网站名字,如果出现...

外国网站的浏览器下载(外国网站的浏览器下载Games)

答,可在浏览器上面下载所需要的视频/音乐的名称,下载完毕后,按所给的排列表找出所需要的视频/音乐。如果是喜欢的视频/音乐它在浏览器里边都有分类,可详细的介绍一下自己吧,还可以在古典音乐或者名著导读介绍...

京东攒机助手(京东攒机在哪)
京东攒机助手(京东攒机在哪)

自己在京东买的配置,以为身边的人能帮忙组装,但是好像超过了个人的认知,所以无奈之下只能在京东找专业人士进行安装,挺快,前一天傍晚下单,第二天上午上班就来了,组装师傅挺好,挺有耐心,业务也挺熟练,走线看起来也不错,买的机箱是师傅从来没有接触过...

2025-11-14 22:03 off999

腾讯电脑管家和360哪个好(腾讯电脑管家好用还是360好用)

两个都很好。1.腾讯电脑管家和360卫士都是电脑上最常见的免费杀毒软件,两款软件在病毒查杀上都是首屈一指的。2.360卫士在功能上十分丰富,从木马查杀到电脑清理以及优化加速都是一应俱全的,而且还集成了...

笔记本突然没声音(笔记本突然没声音是什么原因)

可能是因为电脑声音驱动设备故障导致电脑没有声音。解决方法:使用Win+X快捷键,然后在弹出的窗口中点击“设备管理器”选项,之后点击“打开声音、视频和游戏控制器”选项,打开的属性界面查看运行是否正常,或...

大白菜一键装机win7系统(大白菜装系统教程win7)

1.电脑开机按f2或del进bios里面,启动项里面设置U盘启动,保存退出重启。2.键盘上一直按f12或f10,选择大白菜的u盘,进入pe界面,键盘按上下健移动,选择2003pe或win10pe,按回...

迅雷在线资源网观看(迅雷资源网 1080p 下载)
  • 迅雷在线资源网观看(迅雷资源网 1080p 下载)
  • 迅雷在线资源网观看(迅雷资源网 1080p 下载)
  • 迅雷在线资源网观看(迅雷资源网 1080p 下载)
  • 迅雷在线资源网观看(迅雷资源网 1080p 下载)

取消回复欢迎 发表评论: