睡眠排序法_python协程的应用

本文介绍了两种非传统排序算法——猴子排序和睡眠排序。猴子排序利用随机性在理论上可以将数组排序;睡眠排序则通过创建多个协程,让每个协程根据元素值沉睡相应时间后输出元素,实现排序。

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

有一种排序算法大名鼎鼎,这种算法叫做睡眠排序

与它同样久负盛名的算法叫做猴子排序。根据无限猴子定理:一只猴子随机在打字机键盘上按键,在无穷久的时间之后打出法国国家图书馆的每一本图书的概率为100%。同样的,在无穷久的时间内,猴子也会把一个无序数组排列好。

猴子排序算法写起代码来非常简单:

import random


class Monkey:
    def __init__(self, arr):
        self.arr = arr
        self.length = len(arr)

    def sort(self):
        while not self.is_sorted():
            random.shuffle(self.arr)

    def is_sorted(self):
        for i in range(self.length-1):
            if self.arr[i] > self.arr[i+1]:
                return False
        return True

    def show(self):
        print(self.arr)

if __name__ == '__main__':
    m = Monkey([3, 1, 2])
    m.sort()

下面主要写一写睡眠排序。

它的原理脑洞大开:对每个元素开一条线程,线程沉睡的时间为元素的值,线程醒来之后就输出元素。

这里不用线程,用一下python的协程。排序算法适用于非负数的数列。

对每个元素k开一条协程,每条协程睡眠k单位。

 

import asyncio
import random


class SleepSort:
    """
    睡眠排序法,针对每个元素k开一条协程,每条协程睡眠k单位秒,随后加入序列中
    每个伙计给条被子,睡醒了起来打卡
    """
    def __init__(self, arr):
        self.arr = arr
        self.record = []        # 存储,伙计们睡醒了就来这里打卡

    def sort(self):
        loop = asyncio.get_event_loop()                 # 开一个事件循环(造个东北大炕)
        tasks = [self._sleeping(i) for i in self.arr]   # 创建n个睡觉的任务(给n条被子)
        loop.run_until_complete(asyncio.wait(tasks))    # 闭上眼,大伙儿都睡
        loop.close()                                    # 协程关闭(拆了大炕)
        self.arr = self.record

    @asyncio.coroutine
    def _sleeping(self, k):                     # 每个伙计都要执行的睡觉任务
        yield from asyncio.sleep(k * 0.02)      # 乘个系数,睡得太久也不好
        print(k)
        self.record.append(k)                   # 睡醒了去打卡

    def show(self):
        # 打印数组
        print(self.arr)

if __name__ == '__main__':
    lst = list(range(100))
    random.shuffle(lst)
    s = SleepSort(lst)
    s.show()
    s.sort()
    s.show()

代码写完,运行……

[80, 15, 74, 4, 83, 26, 96, 14, 93, 63, 69, 89, 55, 57, 0, 66, 98, 37, 2, 71, 68, 95, 28, 62, 25, 76, 34, 31, 39, 20, 87, 47, 64, 40, 53, 3, 36, 6, 77, 60, 32, 9, 1, 90, 75, 46, 61, 8, 56, 10, 13, 72, 58, 97, 21, 84, 17, 86, 48, 67, 38, 23, 50, 70, 19, 41, 65, 45, 27, 30, 44, 88, 24, 79, 43, 7, 59, 81, 54, 11, 91, 29, 35, 52, 16, 99, 5, 78, 42, 82, 33, 49, 22, 73, 92, 85, 94, 18, 12, 51]
0
1
2
3
4
5
6
7
8
9
.
.
.
95
96
97
98
99
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

进程已结束,退出代码0

没毛病。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值