常用排序算法代码(Python)实现

目录

1.冒泡排序

改进的冒泡排序

2.堆排序

3.希尔排序

4.快速排序

5.二分插入排序

6.简单选择排序


文章开头先给大家推荐一个学习算法的一个非常不错的网站:Hello算法。相信很多小伙伴都听说过并且也在该网站学习过算法。

《Hello 算法》是一本开源免费、新手友好的数据结构与算法入门书。

  • 全书采用动画图解,引导初学者探索数据结构与算法的“知识地图”,为算法学习与刷题打下坚实基础;
  • 源代码皆可一键运行,使读者在实践练习中提升编程技能,了解数据结构与算法的底层实现和工作原理;

Hello 算法Github代码仓库:https://github.com/krahets/hello-algo 

Hello 算法网页版:https://www.hello-algo.com/chapter_preface/

多语言支持

目前已将代码译写至 Java, C++, Python, Go, JavaScript, TypeScript, C#, Swift, Zig 等多种语言,可满足大多数小伙伴需要。

内容结构

该版本共包含 12 章内容,写在前面、引言、复杂度分析、数据结构简介、数组与链表、栈与队列、散列表、树、堆、图、查找算法、排序算法、附录。

但是下文中的代码都是我自己以前根据不同排序算法思路写的,呢时候还不知道有这个网站,这个网站也是我的一个师兄告诉我的,真心觉得不错,所以推荐给大家。所以我不是照搬该网站里面的代码,当然我自己写的肯定不如人家网站里面写得好。

在计算机程序中,排序是基本且至关重要的操作。从搜索引擎优化结果列表、数据分析、至数据库查询优化,几乎所有的技术系统都以某种形式依赖于有效的排序机制。排序算法的效率直接影响了程序的性能,特别是在处理大数据集时。因此,了解和实现常用的排序算法不仅是一个重要的学术练习,同时也是实践编程技能的核心。

排序算法可以根据不同的指标来分类:它们的执行时间(时间复杂度)、它们在执行中需要的额外空间(空间复杂度)、算法的稳定性(是否保持相等元素的初始顺序),以及它们是递归地还是迭代地执行任务。这些指标帮助我们决定在具体应用中选择哪一个算法。例如,一个内存敏感的应用可能需要一个空间复杂度低的排序算法,而在对速度要求极高的系统中,选择一个时间复杂度低的排序算法是至关重要的。

在本篇博客中,我们将深入探讨几种常用的排序算法,并提供它们的Python代码实现,以供所有级别的编程爱好者学习和使用。


1.冒泡排序

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

代码示例:

# 从输入中获取一组整数,并将其转换为列表
b = list(map(int, input().split(' ')))

# 获取列表的长度
n = len(b)

# 对列表进行冒泡排序
for i in range(1, n):
    # 对每个元素进行比较
    for j in range(n - i):
        # 如果当前元素大于下一个元素
        if b[j] > b[j + 1]:
            # 交换两个元素的位置
            t = b[j]
            b[j] = b[j + 1]
            b[j + 1] = t

# 打印排序后的列表
print(b)

改进的冒泡排序

这个改进的版本在每一轮遍历后都会检查是否已经完成排序,如果已经完成则提前结束,从而提高效率。

代码示例:

# 从输入中获取一组整数,并将其转换为列表
b = list(map(int, input().split(' ')))

# 获取列表的长度
n = len(b)

# 初始化一个标志位,用于标记是否已经完成排序
flag = 1

# 对列表进行冒泡排序
for i in range(1, n):
    # 如果在上一轮遍历中没有发生交换,说明已经完成排序,可以提前结束
    if flag == 1:
        flag = 0
        # 对每个元素进行比较
        for j in range(n - i):
            # 如果当前元素大于下一个元素
            if b[j] > b[j + 1]:
                # 标记发生了交换
                flag = 1
                # 交换两个元素的位置
                t = b[j]
                b[j] = b[j + 1]
                b[j + 1] = t

# 打印排序后的列表
print(b)

2.堆排序

堆排序是一种基于比较的排序算法,它将待排序的序列视为一个完全二叉树,然后通过调整节点的位置,使得每个节点都大于或等于其子节点,形成一个大顶堆。然后将堆顶元素与最后一个元素交换,然后对剩余的元素重新调整为大顶堆,如此反复,直到所有元素都被排序。

代码示例:

# 从输入中获取一组整数,并将其转换为列表
b = list(map(int, input().split(' ')))

# 初始化一个列表a,第一个元素为0,其余元素为b的元素
a = [0]
for i in b:
    a.append(i)


# 定义堆调整函数,s为要调整的节点,m为堆的大小
def HeapAjust(a, s, m):
    # rc为要调整的节点的值
    rc = a[s]
    # j为s的左子节点
    j = 2 * s
    # 如果左子节点在堆内,则进入循环
    while (j <= m):
        # 如果右子节点在堆内,且右子节点的值大于左子节点的值,则j指向右子节点
        if j < m and a[j] < a[j + 1]:
            j += 1
        # 如果要调整的节点的值大于等于j节点的值,则退出循环
        if rc >= a[j]:
            break
        # 否则,将j节点的值赋给s节点,然后s指向j节点,j指向s的左子节点
        a[s] = a[j]
        s = j
        j *= 2
    # 将rc的值赋给s节点
    a[s] = rc


# 定义堆排序函数,n为要排序的元素个数
def HeapSort(a, n):
    # 从最后一个非叶子节点开始,对每个节点进行堆调整
    for i in range(n // 2, 0, -1):
        HeapAjust(a, i, n)
    # 从最后一个元素开始,将堆顶元素与最后一个元素交换,然后对剩余的元素进行堆调整
    for i in range(n, 1, -1):
        t = a[1]
        a[1] = a[i]
        a[i] = t
        HeapAjust(a, 1, i - 1)


# 如果是主程序,则调用堆排序函数,然后打印排序后的结果
if __name__ == '__main__':
    HeapSort(a, len(a) - 1)
    print(a)
    # 打印排序后的结果,从第二个元素开始打印,因为第一个元素是0
    for i in range(1, len(a)):
        print(a[i], end=' ')

3.希尔排序

希尔排序是一种基于插入排序的算法,通过比较相距一定间隔的元素,我们可以一次交换一对元素,它们可能有很长的距离,然后会导致数据移动到更接近它最终排序位置。希尔排序是非稳定排序算法。

代码示例:

# 从输入中获取一组整数,并将其转换为列表
b = list(map(int, input().split(' ')))

# 初始化一个列表a,第一个元素为0,其余元素为b的元素
a = [0]
for i in b:
    a.append(i)

# 定义希尔排序的增量序列
data = [5, 3, 1]

# 定义希尔排序函数,a为要排序的列表,dk为当前的增量
def xier_sort(a, dk):
    # i从dk+1开始,因为前dk个元素默认为已排序的
    i = dk + 1
    # 如果i小于列表的长度,则进入循环
    while (i < len(a)):
        # 如果当前元素小于它前面的元素
        if a[i] < a[i - dk]:
            # 将当前元素的值保存到a[0]
            a[0] = a[i]
            # j为当前元素前面的元素
            j = i - dk
            # 如果j大于0,则进入循环
            while (j > 0):
                # 如果a[0]小于a[j]
                if a[0] < a[j]:
                    # 将a[j]的值赋给a[j+dk]
                    a[j + dk] = a[j]
                    # j减去dk
                    j = j - dk
                else:
                    break
            # 将a[0]的值赋给a[j+dk]
            a[j + dk] = a[0]
        # i加1
        i = i + 1
    # 返回排序后的列表
    return a

# 对每个增量,调用希尔排序函数
for dk in data:
    a = xier_sort(a, 1)

# 打印排序后的结果,从第二个元素开始打印,因为第一个元素是0
print(a)
for i in range(1, len(a)):
    print(a[i], end=' ')

4.快速排序

快速排序是一种高效的排序算法,它使用分治法(Divide and Conquer)策略来把一个序列(list)分为两个子序列(sub-lists),步骤是:

  1. 从序列中挑出一个元素,作为"基准"(pivot),
  2. 重新排序序列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作,
  3. 递归地(recursive)把小于基准值元素的子序列和大于基准值元素的子序列排序。

代码示例:

# 从输入中获取一组整数,并将其转换为列表
b = list(map(int, input().split(' ')))

# 初始化一个列表a,第一个元素为0,其余元素为b的元素
a = [0]
for i in b:
    a.append(i)


# 定义快速排序函数,low为排序开始的位置,high为排序结束的位置
def QSort(a, low, high):
    if low < high:
        # 找出基准的位置
        pivotloc = Partition(a, low, high)
        # 对基准左边的序列进行快速排序
        QSort(a, low, pivotloc - 1)
        # 对基准右边的序列进行快速排序
        QSort(a, pivotloc + 1, high)


# 定义分区函数,low为排序开始的位置,high为排序结束的位置
def Partition(a, low, high):
    # 将基准值保存在a[0]
    a[0] = a[low]
    pivotkey = a[low]
    while (low < high):
        # 从右向左找到第一个小于基准的值
        while (low < high and a[high] >= pivotkey):
            high -= 1
        # 将这个值移动到左边
        a[low] = a[high]
        # 从左向右找到第一个大于基准的值
        while (low < high and a[low] <= pivotkey):
            low += 1
        # 将这个值移动到右边
        a[high] = a[low]
    # 将基准值放到正确的位置
    a[low] = a[0]
    # 返回基准的位置
    return low


# 如果是主程序,则调用快速排序函数,然后打印排序后的结果
if __name__ == '__main__':
    QSort(a, 1, len(a) - 1)
    print(a)
    # 打印排序后的结果,从第二个元素开始打印,因为第一个元素是0
    for i in range(1, len(a)):
        print(a[i], end=' ')

5.二分插入排序

二分插入排序是一种改进的插入排序,它在插入元素时使用二分查找的方法找到元素的插入位置,从而减少了比较的次数,提高了排序的效率。

代码示例:

# 从输入中获取一组整数,并将其转换为列表
yuanshi = list(map(int, input().split(' ')))

# 初始化一个列表shaobing,第一个元素为0,其余元素为yuanshi的元素
shaobing = [0]
for i in yuanshi:
    shaobing.append(i)
yuanshi = shaobing
print(yuanshi)

# 从第五个元素开始,对每个元素进行二分插入排序
for i in range(5, len(yuanshi)):
    # 将当前元素的值保存到yuanshi[0]
    yuanshi[0] = yuanshi[i]
    # 初始化low和high
    low = 1
    high = i - 1
    # 使用二分查找找到元素的插入位置
    while (low <= high):
        mid = (low + high) // 2
        if (yuanshi[0] < yuanshi[mid]):
            high = mid - 1
        else:
            low = mid + 1
    # 将元素插入到正确的位置
    for j in range(i - 1, high, -1):
        yuanshi[j + 1] = yuanshi[j]
    yuanshi[high + 1] = yuanshi[0]
# 打印排序后的结果
print(yuanshi)

6.简单选择排序

简单选择排序是一种基本的排序算法,这种算法首先在未排序的序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

代码示例:

# 从输入中获取一组整数,并将其转换为列表
b = list(map(int, input().split(' ')))

# 对列表进行简单选择排序
for i in range(len(b) - 1):
    # 初始化最小元素的位置
    k = i
    # 从未排序的元素中找到最小元素的位置
    for j in range(i + 1, len(b)):
        if b[j] < b[k]:
            k = j
    # 如果最小元素的位置不是i,交换b[i]和b[k]
    if k != i:
        t = b[i]
        b[i] = b[k]
        b[k] = t

# 打印排序后的列表
print(b)

# 以空格分隔的方式打印排序后的列表
for i in b:
    print(i, end=' ')

  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值