常用排序 算法

常用排序算法:

 

 检测算法执行效率:

# 检测算法执行效率
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):  #一开始-1是因为要拿出第一个数来作为比较值,减i 是因为一次循环比较都会确认一个最大的数。
            if li[j]<li[j+1]:
                li[j],li[j+1] = li[j+1],li[j]
                status = True
        if not status:
            return

选择:

#选择排序
# """
# 1.从列表中拿出第1个数,并标记一下,然后在拿着这个数去和其他的数比较大小,如果第一个数大(小),就让他们交换一下位置,
# 2. 继续拿着交换来的小数去和剩下的数比较,直到第一个数最小(最大) ,之后拿出第二个数重复第一个数的历程,以此类推
# """
@caltime
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 后面没有值,同时j不可能小于0
            li[j+1] = li[j]  #k往前面推一个位置
            j = j - 1  #k 后面的 值的索引
        li[j+1] = tmp  # 插入k前面

快排:

#拿出一个元素,使其归位后,大的在其右边,小的在左边;得到一个相对有序的列表,然后以其为中间数分割线列表,
# 重复上一步归位,以此类推,最终得到一个 有序列表

### O(n) #快排
def partition(li, left, right):
    tmp = li[left]
    while left < right:
        while left < right and li[right] >= tmp:   #和右边数比
            right = right - 1
        li[left] = li[right]
        while left < right and li[left] <= tmp:    #和左边数比
            left = left + 1
        li[right] = li[left]
    li[left] = tmp    # 归位:通过左右两边确认里li[left] 的下标
    return left

## 时间复杂度: O(nlogn)
def _quickSort(li, left, right):
    if left < right:
        mid = partition(li, left, right) ### O(n)  拿到归位后的数,对左右两边循环归位
        _quickSort(li, left, mid - 1)   ### O(logn)
        _quickSort(li, mid + 1, right)
@caltime
def quickSort(li, left, right):
    _quickSort(li, left, right)

归并:

###  时间复杂度: O(nlogn)
def merge(li, low, mid, right):
    i = low
    j = mid + 1
    ltmp = []
    while i <= mid and j <= right:
        if li[i] < li[j]:
            ltmp.append(li[i])
            i = i + 1
        else:
            ltmp.append(li[j])
            j = j + 1

    while i <= mid:
        ltmp.append(li[i])
        i = i + 1

    while j <= right:
        ltmp.append(li[j])
        j = j + 1

    li[low:right+1] = ltmp

def mergeSort(li, low, high):
    if low < high:
        mid = (low + high) // 2

mergeSort(li, low, mid) mergeSort(li, mid + 1, high)
merge(li, low, mid, high) #这个一定的放最后

 

posted @ 2019-06-15 23:01  萤huo虫  阅读(92)  评论(0编辑  收藏  举报