python九种排序代码实现

简介: python九种排序代码实现

用python实现常见的九种排序

冒泡排序


列表每相邻的数,如果前面比后面大,则交换这两个数一趟排序完成后,则无序区减少一个数,有序增加一个数


from cal_time import cal_time
@cal_time
def bubble_sort(li):
    for i in range(len(li)-1):
        exchange = False
        for j in range(len(li)-i-1):
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]
                exchange = True
        if not exchange:
            return


选择排序


# 算法关键: 有序区和无序区, 记录无序区最小数的位置
def select_sort(li):
    for i in range(len(li)-1):
        min_loc = i
        for j in range(i+1,len(li)):
            if li[j] < li[min_loc]:
                min_loc = j
        li[i], li[min_loc] = li[min_loc], li[i]


插入排序


def insert_sort(li):
    for i in range(1, len(li)):
        tmp = li[i]
        j = i-1
        # 找插入的位置
        # 从右往左比较,如果tmp小于l[j],l[j]他的位置就向右移一个位置,
        while j >= 0 and li[j] > tmp:
            li[j+1] = li[j]
            j = j-1
        li[j+1] = tmp


快速排序


def partition(li, left, right):
    # 将最左边的元素给tmp
    tmp = li[left]
    while left < right:
        while left < right and li[right]>=tmp:  # 从右面找出比tmp小的数
            right -= 1
        li[left] = li[right]    # 将右边第一个小于tmp的数放到左边的空位上
        while left < right and li[left] <= tmp:   # 从左边找出比tmp大的数
            left += 1
        li[right] = li[left]   # 将左边第一个大于tmp的数放到右边刚才腾出来的空位上
    li[left] = tmp       # 将tmp归位,放到了左边全比它小,右面全比它大的位置,也就是它最后应在的位置
    return left      # 这个left代表的就是tmp位置的索引
def quick_sort(li, left, right):
    if left < right:  # 至少有两个元素,是判断递归是否停止的条件
        mid = partition(li, left, right)
        quick_sort(li,left, mid-1)
        quick_sort(li, mid+1,right)


堆排序


def sift(li, low, high):
    """
    :param li: 列表
    :param low: 堆的根节点位置
    :param high: 堆的最后一个元素的位置
    :return:
    """
    i = low      # 最开始指向根节点的
    j = 2*i+1   # j 开始是左孩子
    tmp = li[low]  # 把堆顶存起来
    while j <= high:
        if j + 1 <= high and li[j+1] > li[j]:   # 如果右孩子有且比较大
            j = j+1   # j指向右孩子
        if li[j] > tmp:
            li[i] = li[j]
            i = j
            j = 2*i+1
        else:         # tmp更大把tmp放到i的位置吧
            li[i] = tmp     # 把tmp放到某一领导位置
            break
    else:
        li[i] = tmp   #  把tmp放到叶子节点
def heap_sort(li):
    n = len(li)
    for i in range((n-2)//2-1, -1, -1):
        # i 标示建堆的时候调整部分的根下标
        sift(li, i, n-1)
    # 堆建造完成
    for i in range(n-1,-1, -1):
        # i 指向当前堆的最后一个元素
        li[0], li[i] = li[i], li[0]
        sift(li, 0, i-1)    # i-1 是新的high


归并排序


def marge(li, low,mid,high):
    """
    :param li:  列表
    :param low:  第一个有序列表的起始位置
    :param mid: 分界位置的索引
    :param high:   第二个有序列表的结尾位置
    :return:
    """
    i = low
    j = mid+1
    ltmp = []
    while i <= mid and j <= high:
        if li[i] <= li[j]:
            ltmp.append(li[i])
            i += 1
        else:
            ltmp.append(li[j])
            j += 1
    # while执行完,肯定有一部分没有数了
    # print(li)
    # print(len(li))
    while i <= mid:
        ltmp.append(li[i])
        i += 1
    while j <= high:
        ltmp.append(li[j])
        j += 1
    li[low:high+1] = ltmp     # 给切片赋值
# li = [1,2,5,8,9,4,5,6,7,8]
# print((len(li)-1)//2)
# marge(li, 0,4,len(li)-1)
# # print(li)
def merge_sort(li,low,high):
    if high > low:    # 至少有两个元素,递归
        mid = (low+high) // 2
        merge_sort(li, low, mid)
        merge_sort(li, mid+1, high)
        marge(li, low, mid, high)


希尔排序


def insert_sort_gap_(li,gap):
    for i in range(gap,len(li)):    # i 代表摸到的牌的下标
        tmp = li[i]
        j = i-gap        # j指的是手中的牌的下标
        while j >= 0 and li[j] > tmp:
            li[j+gap] = li[j]     # 将大的数放到后面
            j -= gap
        li[j+gap] = tmp
def shell_sort(li):
    d = len(li)//2
    while d >= 1:
        insert_sort_gap_(li,d)
        d //= 2


计数排序


def count_sort(li,max_count=100):
    count = [0 for _ in range(max_count+1)]
    for val in li:
        count[val] += 1
    li.clear()
    for ind, val in enumerate(count):
        for i in range(val):
            li.append(ind)


基数排序


def radix_sort(li):
    max_num = max(li)
    it = 0
    while 10**it <= max_num:
        buckets = [[] for _ in range(10)]
        # 分桶
        for var in li:
            digit = (var // 10**it) % 10
            buckets[digit].append(var)
        # 将数重新放回li
        li.clear()
        for buc in buckets:
            li.extend(buc)
        it += 1
相关文章
|
1月前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
49 6
|
1天前
|
数据挖掘 数据处理 开发者
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
20 10
|
24天前
|
Python
课程设计项目之基于Python实现围棋游戏代码
游戏进去默认为九路玩法,当然也可以选择十三路或是十九路玩法 使用pycharam打开项目,pip安装模块并引用,然后运行即可, 代码每行都有详细的注释,可以做课程设计或者毕业设计项目参考
63 33
|
25天前
|
JavaScript API C#
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
45 10
|
1月前
|
数据可视化 Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
通过这些思维导图和分析说明表,您可以更直观地理解和选择适合的数据可视化图表类型,帮助更有效地展示和分析数据。
87 8
|
1月前
|
API Python
【Azure Developer】分享一段Python代码调用Graph API创建用户的示例
分享一段Python代码调用Graph API创建用户的示例
64 11
|
1月前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
51 11
|
1月前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
1月前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
63 6
|
1月前
|
Python
如何提高Python代码的可读性?
如何提高Python代码的可读性?
61 4

热门文章

最新文章