冒泡、选择、插入排序的Python实现

本文深入讲解三种经典排序算法:冒泡排序、选择排序和插入排序。通过详细代码解析,帮助读者理解每种算法的工作原理及其实现过程。文章适合初学者入门及进阶学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

冒泡排序

选择排序

插入排序

完整代码


冒泡排序

原理就不讲了, 只讲程序怎么理解,首先讲序列的长度n计算出来,然后进行n-1轮的迭代,为啥是n-1轮呢?因为最后一轮的时候,就已经迭代好了,不用再迭代了。再定义一个j进行(n-1-i)轮迭代,这是因为当经过i轮迭代后,后面的i个数字已经排好序了,不需要再去管他们了,所以直接从n-1-i开始遍历,如果每个前面的值大于后面的,那就把这两个值进行交换。

PS:交换的时候,利用Python独特的语法特点,不需要设置中间变量。


def bubble_sort(seq):  # O(n^2), n(n-1)/2 = 1/2(n^2 + n)
    n = len(seq)
    for i in range(n-1):
        print(seq)    # 我打印出来让你看清楚每一轮最高、次高、次次高...的小朋友会冒泡到右边
        for j in range(n-1-i):  # 这里之所以 n-1 还需要 减去 i 是因为每一轮冒泡最大的元素都会冒泡到最后,无需再比较
            if seq[j] > seq[j+1]:
                seq[j], seq[j+1] = seq[j+1], seq[j]
        print(seq)

选择排序

先找全序列值最小的数,排在第一位,再找全序列次小的数,排在第二位,再找全序列次次小的数排在第三位,依次类推,一圈下来,就排好了。

同样,也是开始(n-1)轮循环,然后,记录最小值的索引,如果最小值的索引(min_idx)所对应的值不是整个序列的循环次数(i)就把它俩对应的数进行交换。(因为默认的第一次循环找出最小值放到第一个位置;第二次循环找出次小值放到第二个位置依次类推)

def select_sort(seq):
    n = len(seq)
    for i in range(n-1):
        min_idx = i    # 我们假设当前下标的元素是最小的
        for j in range(i+1, n):    # 从 i 的后边开始找到最小的元素,得到它的下标
            if seq[j] < seq[min_idx]:
                min_idx = j    # 一个 j 循环下来之后就找到了最小的元素它的下标
        if min_idx != i:    # swap
            seq[i], seq[min_idx] = seq[min_idx], seq[i]

插入排序

默认左边的是有序的, range(1,n)从第二个元素作为当前元素开始进行查找,如果当前元素的左边的元素有比它大的值,那么就把这个当前元素插入到比它大的值的前面(pos是为了计数,遍历位于当前元素左边的所有元素用的)然后,开始第三个元素,第四个元素,直至都遍历一遍。

插入的意思是,把当前元素插到对应的位置,至于其他的元素位置,再插入点前面的不用变,再它插入点后面的就顺着都加一就行了。

def insertion_sort(seq):
    """ 每次挑选下一个元素插入已经排序的数组中,初始时已排序数组只有一个元素"""
    n = len(seq)
    print(seq)
    for i in range(1, n):
        value = seq[i]    # 保存当前位置的值,因为转移的过程中它的位置可能被覆盖
        # 找到这个值的合适位置,使得前边的数组有序 [0,i] 有序
        pos = i
        while pos > 0 and value < seq[pos-1]:
            seq[pos] = seq[pos-1]  # 如果前边的元素比它大,就让它一直前移
            pos -= 1
        seq[pos] = value    # 找到了合适的位置赋值就好
        print(seq)

 

完整代码

test_**是对应的单侧代码。

# -*- coding: utf-8 -*-


import random


def bubble_sort(seq):  # O(n^2), n(n-1)/2 = 1/2(n^2 + n)
    n = len(seq)
    for i in range(n-1):
        print(seq)    # 我打印出来让你看清楚每一轮最高、次高、次次高...的小朋友会冒泡到右边
        for j in range(n-1-i):  # 这里之所以 n-1 还需要 减去 i 是因为每一轮冒泡最大的元素都会冒泡到最后,无需再比较
            if seq[j] > seq[j+1]:
                seq[j], seq[j+1] = seq[j+1], seq[j]
        print(seq)


def test_bubble_sort():
    seq = list(range(10))  # 注意 python3 返回迭代器,所以我都用 list 强转了,python2 range 返回的就是 list
    random.shuffle(seq)   # shuffle inplace 操作,打乱数组
    sorted_seq = sorted(seq)  # 注意呦,内置的 sorted 就不是 inplace 的,它返回一个新的数组,不影响传入的参数
    bubble_sort(seq)
    assert seq == sorted_seq


def select_sort(seq):
    n = len(seq)
    for i in range(n-1):
        min_idx = i    # 我们假设当前下标的元素是最小的
        for j in range(i+1, n):    # 从 i 的后边开始找到最小的元素,得到它的下标
            if seq[j] < seq[min_idx]:
                min_idx = j    # 一个 j 循环下来之后就找到了最小的元素它的下标
        if min_idx != i:    # swap
            seq[i], seq[min_idx] = seq[min_idx], seq[i]


def test_select_sort():
    seq = list(range(10))
    random.shuffle(seq)
    sorted_seq = sorted(seq)
    select_sort(seq)
    assert seq == sorted_seq


def insertion_sort(seq):
    """ 每次挑选下一个元素插入已经排序的数组中,初始时已排序数组只有一个元素"""
    n = len(seq)
    print(seq)
    for i in range(1, n):
        value = seq[i]    # 保存当前位置的值,因为转移的过程中它的位置可能被覆盖
        # 找到这个值的合适位置,使得前边的数组有序 [0,i] 有序
        pos = i
        while pos > 0 and value < seq[pos-1]:
            seq[pos] = seq[pos-1]  # 如果前边的元素比它大,就让它一直前移
            pos -= 1
        seq[pos] = value    # 找到了合适的位置赋值就好
        print(seq)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值