常见的排序方法(Python实现)

主程序如下:

from random import randint
import time
import copy


GA_MAX = 19		#待排序的数据的数量
ga = [randint(0, 199) for i in range(GA_MAX)]	#待排序的数据
ga_copy = []	#用于检测排序结果

def print_ga():
    # print(ga)
    print(''.join(str(i) + ' ' for i in ga))


def random_ga():
    ga = [randint(0,GA_MAX-1) for i in range(20)]


def check_rsult():		#检查排序结果:期望是从大到小排序
    for i in range(GA_MAX):
        if ga_copy[i] not in ga:
            return False
    for i in range(GA_MAX-1):
        if ga[i] < ga[i+1]:
            return False
    return True

def sort_main():
    global ga_copy
    print_ga()
    ga_copy = copy.deepcopy(ga)
    time_start = time.perf_counter()

	# 具体的算法写在这里,从小到大 或者 从大到小
    # bubble_sort()
    # select_sort()
    # insert_sort()
    # insert_sort_half()
    # quick_sort()
    # heap_sort()
    # shell_sort()
    # merge_sort()
    
    time_cost = (time.perf_counter() - time_start) * 1000
    print('time_cost: {:g}ms'.format(time_cost))
    print_ga()
    print('check_rsult = ', check_rsult())
    return time_cost    # ms


if __name__ == '__main__':
    sort_main()

运行结果参考:

27 93 12 43 111 4 67 1 121 118 112 48 170 101 19 119 62 177 23 
time_cost: 0.044ms
177 170 121 119 118 112 111 101 93 67 62 48 43 27 23 19 12 4 1 
check_rsult =  True
#冒泡排序  从小到大和从大到小
def bubble_sort():  # O(n*n)  稳定
    """冒泡排序"""
    # ascend
    for j in range(GA_MAX):
        for i in range(GA_MAX-j-1):
            if ga[i] > ga[i+1]:
                ga[i], ga[i+1] = ga[i+1], ga[i]

def bubble_sort():
    for i in range(GA_MAX-1):
        for j in range(0, GA_MAX-i-1, 1):
            if ga[j] < ga[j+1]:
                ga[j], ga[j+1] = ga[j+1], ga[j]
# 如果向稳定排序,方法一,每次交换改为向后整体移位  方法二,组件新的数组
def select_sort():  # O(n*n)  不稳定
    """选择排序"""
    # ascend
    for j in range(GA_MAX):
        t = j
        for i in range(j + 1, GA_MAX):
            if ga[i] < ga[t]:
                t = i
        ga[j], ga[t] = ga[t], ga[j]
        
def select_sort():
    for i in range(GA_MAX-1):
        t = i
        for j in range(i+1, GA_MAX, 1):
            if ga[j] > ga[t]:
                t = j
        if t != i:
            ga[i], ga[t] = ga[t], ga[i]
def insert_sort():    # O(n*n)  稳定
    """插入排序"""
    # ascend
    for i in range(1, GA_MAX):
        for j in range(i, 0, -1):   # ga[i] 就是本次要插入的数据
            if ga[j] < ga[j-1]:     # 比较次数较多
                ga[j-1], ga[j] = ga[j], ga[j-1]     # 牺牲交换次数,换来代码整洁
            # 前面已经是有序数据,仍然要比较i次


def insert_sort_2():
    for i in range(1, GA_MAX):
        focus = ga[i]
        j = 0
        for j in range(i-1, -1, -1):
            if focus < ga[j]:       # 增加了break,找到即停,但这里使用的是顺序查找,最坏情况要比较i次
                ga[j+1] = ga[j]     # 相比上面算法,这里只做一次赋值
            else:
                j += 1  # 更新为focus的位置
                break   # 找到插入位置,就停止比较
        ga[j] = focus


def insert_sort_half():
    for i in range(1, GA_MAX):
        focus = ga[i]

        # 需要比较[0,i-1], 将顺序查找改为折半查找
        a = 0
        b = i-1
        j = 0
        while b >= a:
            j = int((b - a) / 2) + a
            if focus < ga[j]:
                b = j-1
                if b >= 0 and ga[b] <= focus:
                    break   # j 就是focus的位置
                elif j == 0:
                    break   # j 就是focus的位置
            else:
                a = j+1
                if a <= i-1 and ga[a] > focus:
                    j = a
                    break   # j 就是focus的位置
                elif j == i-1:
                    j = a
                    break   # j 就是focus的位置

        for t in range(i, j, -1):
            ga[t] = ga[t-1]
        ga[j] = focus

#从大到小-------------------------------------
def insert_sort():
    for i in range(1, GA_MAX, 1):
        t = ga[i]
        for j in range(i-1, -1, -1):
            if ga[j] < t:
                ga[j+1] = ga[j]
                if j == 0:
                    ga[j] = t
            else:
                if j+1 != i:
                    ga[j+1] = t
                break


def half_search(start,end,v):
    a = start
    b = end

    while a <= b:
        n = int(a + (b - a)/2)
        if ga[n] >= ga[v]:
            if n == end or ga[n+1] < ga[v]:
                return n+1
            a = n+1
        else:
            if n == start or ga[n-1] >= ga[v]:
                return n
            b = n-1


def insert_sort_half():
    for i in range(1, GA_MAX, 1):
        t = ga[i]
        n = half_search(0, i-1, i)
        for j in range(i, n, -1):
            ga[j] = ga[j-1]
        ga[n] = t
def quick_sort_do(x, y):
    if x >= y:
        return
    base = ga[x]
    i = x
    j = y
    while i < j:
        while j > i:
            if ga[j] < base:
                ga[i] = ga[j]
                i += 1
                break
            j -= 1
        while i < j:
            if ga[i] > base:
                ga[j] = ga[i]
                j -= 1
                break
            i += 1
    ga[i] = base
    quick_sort_do(x, i-1)
    quick_sort_do(i+1, y)


def quick_sort_ResponseGroup(begin, end):
    pass


def quick_sort():
    """快速排序"""
    # ascend
    quick_sort_do(0, GA_MAX-1)
    #quick_sort_ResponseGroup(0, GA_MAX-1)

#从大到小
def quick_sort_do(start, end):
    if start >= end:
        return
    base = ga[start]
    i = start
    j = end
    while i<j:
        while i<j:
            if ga[j]>base:
                ga[i] = ga[j]
                i += 1
                break
            j -= 1
        while i < j:
            if ga[i] < base:
                ga[j] = ga[i]
                j -= 1
                break
            i += 1
    ga[i] = base
    quick_sort_do(start, i-1)
    quick_sort_do(i+1, end)


def quick_sort():
    quick_sort_do(0, GA_MAX-1)
def heap_sort_do(f, sum):
    if sum <= 1 or f >= GA_MAX:
        return
    l = 2 * f + 1
    r = 2 * f + 2

    # 第一版代码
    '''if l < sum and ga[l] > ga[f]:
        ga[l], ga[f] = ga[f], ga[l]
    if r < sum and ga[r] > ga[f]:
        ga[r], ga[f] = ga[f], ga[r]
    if l < sum:
        heap_sort_do(l, sum)
    if r < sum:
        heap_sort_do(r, sum)'''

    # r 有效,则l必有效
    if r < sum and ga[l] < ga[r]:
        l = r
    if l < sum and ga[l] > ga[f]:
        ga[l], ga[f] = ga[f], ga[l]
        heap_sort_do(l, sum)


def heap_sort():
    """大推排序"""
    # ascend
    # print(''.join(str(i) + ' ' for i in range(GA_MAX)))
    for i in range(GA_MAX-1, 0, -2):    # setup
        f = int((i - 1) / 2)
        heap_sort_do(f, GA_MAX)

    for count in range(1, GA_MAX):
        ga[0], ga[GA_MAX-count] = ga[GA_MAX-count], ga[0]
        heap_sort_do(0, GA_MAX-count)
def shell_sort():
    """希尔排序"""
    gap = int(GA_MAX/2)     # 希尔增量
    while gap >= 1:
        for sub in range(gap):
            for i in range(sub+gap, GA_MAX, gap):   # 每个子序列采用插入排序, x x+gap x+2gap x+3gap
                focus = ga[i]
                j = 0
                for j in range(i - gap, -1, -gap):
                    if focus < ga[j]:  # 增加了break,找到即停,但这里使用的是顺序查找,最坏情况要比较i次
                        ga[j + gap] = ga[j]  # 相比上面算法,这里只做一次赋值
                    else:
                        j += gap  # 更新为focus的位置
                        break  # 找到插入位置,就停止比较
                ga[j] = focus
        gap = int(gap/2)
def merge_sort():
    """归并排序"""
    gt = [0 for i in range(GA_MAX)]
    sub_num = 1     # 各子序列成员最大数
    while sub_num < GA_MAX:
        for i in range(0, GA_MAX, 2 * sub_num):
            j = i + sub_num
            imax = i + sub_num
            if imax > GA_MAX:
                imax = GA_MAX
            jmax = j + sub_num
            if jmax > GA_MAX:
                jmax = GA_MAX
            t = i
            while i < imax and j < jmax:
                if ga[i] > ga[j]:
                    gt[t] = ga[j]
                    j += 1
                else:
                    gt[t] = ga[i]
                    i += 1
                t += 1
            if i == t:  # ga[i-j] 无需改变
                continue

            while i < imax:
                gt[t] = ga[i]
                t += 1
                i += 1
            while j < jmax:
                gt[t] = ga[j]
                t += 1
                j += 1
            for i in range(2*sub_num):  # 将数据拷回去
                t -= 1
                if 0 <= t < GA_MAX:
                    ga[t] = gt[t]
        sub_num = 2*sub_num

#从大到小
# 合并两个任意长度的数组/列表
def merge_do(lstart, lend, rstart, rend):
    l=lstart
    r=rstart
    tlist = []
    while l<=lend and r<=rend:
        if ga[l]>=ga[r]:
            tlist.append(ga[l])
            l += 1
        else:
            tlist.append(ga[r])
            r += 1
    if l<=lend:
        tlist += ga[l:lend+1]
    if r<=rend:
        tlist += ga[r:rend+1]

    l=lstart
    for item in tlist:
        ga[l] = item
        l += 1


def merge_divide(start, end):
    # 1分为2
    num = end-start+1
    smiddle = start+ int(num/2) -1
    if smiddle>start:    # 调用2分接口,从而调用合并接口
        merge_divide(start, smiddle)
    if end>smiddle+1:
        merge_divide(smiddle+1, end)
    # 合并
    if end > start:
        merge_do(start, smiddle, smiddle+1, end)

def merge_sort():
    merge_divide(0, GA_MAX-1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值