主程序如下:
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)