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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

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