有一种排序算法大名鼎鼎,这种算法叫做睡眠排序。
与它同样久负盛名的算法叫做猴子排序。根据无限猴子定理:一只猴子随机在打字机键盘上按键,在无穷久的时间之后打出法国国家图书馆的每一本图书的概率为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
没毛病。