排序算法

 

排序三人组:

冒泡排序

    它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素已经排序完成。

  这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
  
  冒泡排序算法的原理如下
  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  • 针对所有的元素重复以上的步骤,除了第一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

白话文:

"""
一个列表,从中拿一个元素k,和其他元素进行比较,
    如果k大,那么就继续和其他元素比较,
    如果k小,就交换位置(交叉赋值,从而k变成较大的元素)后,继续和其他元素比较,最k会变成最大的那个数,而且还在最右边(从小到大排序)。
确认一个数后,进行第二次比较(比较次数减1,因为k是最大的,所以没必要比),以此类推。
最终得到一个有序列表
ps: 加入第一次比较 k就是最小的,没有和谁交换位置,那么说明这个列表本身就是有序的,后面的比较也就没有必要。

"""

 

选择排序:
  工作原理:
    
是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法


白话文
1.从列表中拿出第1个数,并标记一下,然后在拿着这个数去和其他的数比较大小,如果第一个数大(小),就让他们交换一下位置,
2. 继续拿着交换来的小数去和剩下的数比较,直到第一个数最小(最大) ,之后拿出第二个数重复第一个数的历程,以此类推

插入排序:

  基本思想:

    每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止

  工作解释:

    插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。

  白话文:(一下面实例为对象讲解)

"""
    默认拿列表第一个元素作为有序列表[k,],(一个值就是有序的),所以从第二个值开始和 k 比较大小,
    如:大 插入k前面,
       小 就把 k往前面推一位(空出来的位置刚好留给插入的对比对象)
    然后,在和 k 后面的 值比较大小...
    以此类推,直到 k 后面没有值,就表示比较的对象最小,放在最后(列表第一个位置)。
"""

实例:

import sys
import time,random

sys.setrecursionlimit(10000000)   

#装饰器,实现三者时间复杂度的初步对比
def caltime(func):
    def inner(*args,**kwargs):
        start = time.time()
        func(*args,**kwargs)
        end=time.time()
        print("%s时间是: %s"% (func.__name__,end-start))
    return inner


#冒泡排序
"""
一个列表,从中拿一个元素k,和其他元素进行比较,
    如果k大,那么就继续和其他元素比较,
    如果k小,就交换位置(交叉赋值,从而k变成较大的元素)后,继续和其他元素比较,最k会变成最大的那个数,而且还在最右边(从小到大排序)。
确认一个数后,进行第二次比较(比较次数减1,因为k是最大的,所以没必要比),以此类推。
最终得到一个有序列表
ps: 加入第一次比较 k就是最小的,没有和谁交换位置,那么说明这个列表本身就是有序的,后面的比较也就没有必要。

"""
@caltime
def BubbleSort(li):
    for i in range(len(li)):
        status = False   #加入一个标记状态,一旦有交换位置就(改变)状态,(没变)就直接结束循环
        for j in range(len(li)-i-1):
            if li[j]<li[j+1]:
                li[j],li[j+1] = li[j+1],li[j]
                status = True
        if not status:
            return

#选择排序   1.从列表中拿出第1个数,并标记一下,然后在拿着这个数去和其他的数比较大小,如果第一个数大(小),就让他们交换一下位置,
@caltime    # 2. 继续拿着交换来的小数去和剩下的数比较,直到第一个数最小(最大) ,之后拿出第二个数重复第一个数的历程,以此类推
def selectSort(li):
    for i in range(len(li)):
        biao = i
        for j in range(i+1,len(li)):
            if li[j] < li[biao]:
                li[j],li[biao] = li[biao],li[j]




#插入排序: 每次取一个列表元素与列表中已经排序好的列表段进行比较,然后插入从而得到新的排序好的列表段,最终获得排序好的列表。
"""
    默认拿列表第一个元素作为有序列表[k,],(一个值就是有序的),所以从第二个值开始和 k 比较大小,
    如:大 插入k前面,
       小 就把 k往前面推一位(空出来的位置刚好留给插入的对比对象)
    然后,在和 k 后面的 值比较大小...
    以此类推,直到 k 后面没有值,就表示比较的对象最小,放在最后(列表第一个位置)。
"""
@caltime
def insertSort(li):
    for i in range(1,len(li)):  #从第二个值开始
        tmp = li[i]  #第二个值
        j = i-1  #这样去的 有序列表[k,] k的索引
        #由上分析得知,一直比较的话用while循环
        while  j >= 0 and li[j] > tmp:  #j >= 0 表示 k 后面没有值
            li[j+1] = li[j]  #k往前面推一个位置
            j = j - 1  #k 后面的 值的索引
        li[j+1] = tmp  #插入k前面


li = [random.randint(1,100) for _ in range(10000)]
BubbleSort(li)
# print(li)

li = [random.randint(1,100) for _ in range(10000)]
selectSort(li)

li = [random.randint(1,100) for _ in range(10000)]
insertSort(li)
# print(li)

 

posted @ 2019-04-01 22:49  萤huo虫  阅读(95)  评论(0)    收藏  举报