Python-选择排序

选择排序算法

选择排序虽然是效率不是很高的排序算法,不过它在我们编程的时候还是会经常使用,出场次数有时候可能要比效率更高的那些算法更高。

首先咱们通过一个动图来了解选择排序的过程:

5863482636c750d9e5cb683374fba9d4.gif

通过这个动图,我们可以发现选择排序的过程为:每次一轮遍历都找到当前最小的元素并和未排序元素的第一个元素交换位置。

接下来编写代码:


def sort(arr):
    for j in range(len(arr)-1):    
        minIndex = j
        for i in range(j+1,len(arr),1):
            if(arr[i] < arr[minIndex]):
                minIndex = i
        arr[j],arr[minIndex] = arr[minIndex],arr[j]

def main():
    arr = [3,1,2,4,6,7,8,9,5]
    sort(arr)
    print(arr)

if __name__ == "__main__":
    main()
    pass

执行会输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

使用随机数生成测试用例

通过上面我们已经掌握了选择排序代码的编写了,不过我们会发现,上面代码的测试数组太简单了,只有1-9,这么一段数据集太少了并不能测试我们编写的排序算法到底靠不靠谱。

那如何才能靠谱呢?

你应该已经想到了:加大测试集,增加测试次数,是的,没错,当我们数据量大,测试集非常多的时候这段程序如果依然能正确的进行排序,那我们就可以判断它是一个正确的排序算法了。

好了,问题来了,如何才能生成大量的数据集(比如说一万条)呢?

手写肯定是不行,所以咱们需要通过程序帮我们生成,接下来我们分两步完成生成随机测试用例并测试。

  1. 使用随机数生成大量测试集;
  2. 测试程序是否已经是排好序的状态。
第一步:随机生成1万条测试用例

使用random模块我们就可以生成随机数了
利用random模块的random.randint(a,b)方法就可以生成从ab的随机数。
编写代码:

import random
def getRandomArr(num):
    arr = []
    for i in range(num):
        arr.append(random.randint(0,num))
    return arr

这段代码可以生成num个从0num的随机数。

第二部:测试代码编写

接下来我们需要编写一个函数检测数组是否已经是排好序的。

def isSorted(arr):
    for i in range(len(arr)-1):
        if arr[i] > arr[i+1]:
            return False
    return True

完整代码:


import random

def sort(arr):
    for j in range(len(arr)-1):    
        minIndex = j
        for i in range(j+1,len(arr),1):
            if(arr[i] < arr[minIndex]):
                minIndex = i
        arr[j],arr[minIndex] = arr[minIndex],arr[j]

def main():
    arr = getRandomArr(10000)  #测试一万条数据
    sort(arr)
    
    print(isSorted(arr))#检测是否排好序

#获取随机数
def getRandomArr(num):
    arr = []
    for i in range(num):
        arr.append(random.randint(0,num))
    return arr

#检测是否已排序
def isSorted(arr):
    for i in range(len(arr)-1):
        if arr[i] > arr[i+1]:
            return False
    return True


if __name__ == "__main__":
    main()
    pass

这样子我们就完成了一个选择排序的编写与测试啦。

绘图查看选择排序的算法执行效率

仅仅掌握代码怎么写还不够,我们在深入一层,接下来我们看看选择排序的执行效率,时间复杂度。

咱们在执行代码的时候发现当测试集数据量非常大的时候我们的程序非常慢,其实选择排序算是一种效率较低的排序算法,它的代码执行效率为:O(n^2)

要直观的查看排序所花的时间我们只需要在排序获取当前时间然后在排序之后获取当前时间即可。

获取当前时间使用到的是:datatime库,要获取执行的时间差,需要四个步骤:

  1. 首先导入:import datatime

  2. 获取开始时间,结束时间

  3. 时间相减

  4. 转换格式

示例:

import datetime

startTime = datetime.datetime.now()  #获取开始时间

l = [0] * 10000000   #定义一千万个为0的列表或者处理其他任务

endTime = datetime.datetime.now()  #获取结束时间

time1 = endTime - startTime     #时间相减,得到的是datetime.timedelta对象
#datetime.timedelta对象的'days', 'max', 'microseconds', 'min', 'resolution', 'seconds', 'total_seconds'这些属性是可以调用的
print(time1)   

print(str(time1 .seconds) + "." + str(time1 .microseconds//1000)  + "s")  #输出时间差以秒为单位

在示例中定义了一千万个为0 的列表,执行的结果如下(机器不同时间可能有差别):

0:00:00.064976
0.64s

通过这段代码,我们就可以输出执行某段程序所消耗的时间了。

掌握了如何输出时间差,我们就可以查看选择排序的执行效率了。

完整代码:

import random
import datetime

def sort(arr):
    for j in range(len(arr)-1):    
        minIndex = j
        for i in range(j+1,len(arr),1):
            if(arr[i] < arr[minIndex]):
                minIndex = i
        arr[j],arr[minIndex] = arr[minIndex],arr[j]

def main():
    arr = getRandomArr(1000)
    startTime = datetime.datetime.now()
    sort(arr)
    endTime = datetime.datetime.now()
    #print(isSorted(arr))
    expenseTime = endTime - startTime
    print(str(expenseTime.seconds) + "." + str(expenseTime.microseconds//1000)  + "s")

def getRandomArr(num):
    arr = []
    for i in range(num):
        arr.append(random.randint(0,num))
    return arr

def isSorted(arr):
    for i in range(len(arr)-1):
        if arr[i] > arr[i+1]:
            return False
    return True


if __name__ == "__main__":
    main()
    pass
使用matplotlib生成选择排序执行效率折线图

直接输出数值的方式还是不直观,咱们使用图表的方式展示选择排序算法效率的折线图。


import random
import datetime
import matplotlib.pyplot as plt

def sort(arr):
    for j in range(len(arr)-1):    
        minIndex = j
        for i in range(j+1,len(arr),1):
            if(arr[i] < arr[minIndex]):
                minIndex = i
        arr[j],arr[minIndex] = arr[minIndex],arr[j]

def main():
    timeList = []
    #计算
    l = [10,100,1000,2000,3000,4000,5000,10000]
    for i in l:
        arr = getRandomArr(i)
        startTime = datetime.datetime.now()
        sort(arr)
        endTime = datetime.datetime.now()
        expenseTime = endTime - startTime
        expenseTime = float(str(expenseTime.seconds) + "." + str(expenseTime.microseconds//1000))
        timeList.append(expenseTime)
    #print(isSorted(arr))
    plt.plot(l,timeList)
    plt.show()

def getRandomArr(num):
    arr = []
    for i in range(num):
        arr.append(random.randint(0,num))
    return arr

def isSorted(arr):
    for i in range(len(arr)-1):
        if arr[i] > arr[i+1]:
            return False
    return True


if __name__ == "__main__":
    main()
    pass
Figure_1.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • 选择排序原理:每一趟从元素列表中选取一个最小的元素作为有序序列中第i个元素。意思就是:下标:--------- ...
    4ffde5305e8f阅读 1,815评论 1 3
  • 写一个python 选择排序: range(start, end, step) 产生一个可以迭代的对象。
    流动码文阅读 212评论 0 0
  • 【姓名】刘树寅 【岗位/职业】职业培训师 【经历】二十二年职业经历,十五年人力资源管理工作,十年内训师与培训师经验...
    百舸争流613阅读 194评论 0 0
  • 生活flag 远没行动来的尽心如意 来吧,期待下次见面
    老四肆阅读 125评论 0 0
  • 关于写作,最早的记忆可以追溯到小学三年级。为了备战作文竞赛,我每天去学校图书馆借书,交一篇命题作文给语文老师...
    Chen_Shao阅读 921评论 0 1