鱼C论坛

 找回密码
 立即注册
查看: 2810|回复: 7

[技术交流] 33 - 最日常的排序:插入排序

[复制链接]
发表于 2022-3-20 20:38:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 不二如是 于 2022-6-20 16:15 编辑



相信每位读者都玩过扑克牌吧~

在发好牌后,通常我们会进行整理,拿出一张牌,逐个比较。

大的就插在左边,小的就插在右边。当然这个顺序因人而异。

这么操作一轮后,手里的牌就整理好顺序了。

这和我们今天要讲的拆入排序非常类似~

插入排序法是:

将数列中的元素逐一与已排序好的数据进行比较,进而找到合适的位置并插入。

例如,在排好顺序的两个元素中插入一个元素,就需要将其与其他两个元素做比较,插入合适的位置。

也就是说,将新元素插入数列后,得到的新数列依然是排好序的。

接着再插入另一个元素,以此类推,直至排序完成。

插入排序法最后的结果无非就是两种形式:

递增数列或者递减数列。

假设有一组无序数据:99,23,15,44,3

按照从小到的顺叙进行排序。

第一次排序

先将首位数字 99 放入已排序区域:99

第二次排序

将第二个元素 23 与已排序区域的元素进行比较。

23 小于 99,插入到 99 之前。

此时已排序区域:23,99

第三次排序

将第三个元素 15 与已排序区域元素依次比较。

15 小于 25,15 插入到 25 之前。

此时已排序区域:15,23,99。

第四次排序

将第四个元素 44 与已排序区域元素依次比较。

44 大于 15,23,但小于 99,所以插入到 23 后面,99 后移一个位置。

此时已排序区域:15,23,44,99。

第五次排序

将第五个元素 3 与已排序区域依次比较。

3 小于 15,插入到前面。

此时已排序区域:3,15,23,44,99。

至此排序结束。

接下来我们通过代码实现上述过程。

初始化部分和之前一样:
data = [99,23,15,44,3]
print("原列表:",data)    
print('\n----我是分界线------\n')
insert(data)
我们来实现 choose(data):
def choose(data):
还是要先遍历数据,创建一个变量 t 表示暂存数据:
    for i in range(len(data)):
        t = data[i]
从上面的排序我们知道每次都会从原数列中取出一位。

那么我们的对比值 j 的下标就要 i-1:
        j = i - 1
接下来通过循环排序,判断数据的下标值要大于等于 0 且暂存数据小于原数据。

然后就把所有元素往后移一位并且下标减 1:
 while j >= 0 and t < data[j]:
            data[j+1] = data[j]
            j -= 1
完成循环后,将最小的数据插入最前一个位置:
data[j + 1] = t
剩下就是打印结果:
        for j in range(len(data)):
            print(data[j],end=' ')
        print()
执行看下结果:

2022-03-28_17-47-01.jpg

源码: insert.py.zip (863 Bytes, 下载次数: 5, 售价: 6 鱼币)

接下来我们基于插入排序将 5 位同学的 C 语言考试成绩用插入排序实现从小到大排序,并输出冠亚季军:

2022-03-29_16-54-11.jpg

数据:
data = {'小甲鱼':99,'小田鱼':90,'小电鱼':84,'小由鱼':76,'小申鱼':88}    
因为 data 是字典,我们用 31 讲说过的 list() 将其改为列表,并循环输出:
print("5名同学初始成绩:")
data = {'小甲鱼':99,'小田鱼':90,'小电鱼':84,'小由鱼':76,'小申鱼':88}  
data2 = list(data.items())
print(data2)
for i in data2:
    print(i)
程序初始化部分完成了,剩下就是先调用我们的 insert 函数进行排序啦:
def insert(data):
因为都是插入排序,核心部分代码结构肯定一样:
def insert(data):
    for i in range(len(data)):
        t = data[i]
        j = i - 1
        while j >= 0 and key(t) < key(data[j]):
            data[j+1] = data[j]
            j -= 1
        data[j + 1] = t
由于我们的数据包含人名和成绩,我们需要按照人名排序,即返回每个位置 1 处值即可:
def key(x):
    return x[1]
执行完代码后,data2 中数据就会按照从小到大进行进行排序:
insert(data2)
直接输出后三位值即可:
print('\n----最终排名------\n')
print('冠军是:',data2[4])
print('亚军是:',data2[3])
print('季军是:',data2[2])
因为此时数据长度为 5,我们可以直接通过下标来输出。

如果数据长度不定,那么后三位就是 [len(data)-1],[len(data)-2],[len(data)-3]。

好啦,代码留给你们自己去实现。

源码: insert.py.zip (941 Bytes, 下载次数: 4, 售价: 10 鱼币)

下课!

评分

参与人数 1荣誉 +2 鱼币 +3 贡献 +3 收起 理由
睦ちゃん她爹 + 2 + 3 + 3 鱼C有你更精彩^_^

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-21 10:45:08 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-22 10:12:22 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-22 10:19:36 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-22 23:46:57 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-23 17:55:06 | 显示全部楼层
0.0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-25 20:39:58 | 显示全部楼层
看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-15 11:30:01 | 显示全部楼层
def choose(data):
    for i in range(len(data)):
        t = data[i]
        j = i - 1
        while j >= 0 and data[j] > t:
            data[j + 1] = data[j]
            j -= 1
        data[j + 1] = t
        print(f"第{i+1}次排序后:",end=' ')
        for j in range(len(data)):
            print(data[j], end=' ')
        print()


data = [99, 23, 15, 44, 3]
print("原列表:", data)
print('\n----我是分界线------\n')
choose(data)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-29 09:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表