1. 双调排序: Bitonic Sort
https://blog.youkuaiyun.com/xbinworld/article/details/76408595
复杂度O(n(logn)(logn)):https://www.cnblogs.com/bester/archive/2011/12/20/3255783.html
缺点:works only when size of input is a power of 2.
优点:适合并行
My stupid code:
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 31 10:14:28 2019
@author: yue zhang
E-mails: yuezh2015@163.com
"""
import numpy as np
def bitonic_to_order(data,ascend):
data_num = len(data)
data_mid = int(data_num/2)
d_min = []
d_max = []
if data_mid <1:
return data
if ascend == True:
for i in range(data_mid):
if data[i]<data[i+data_mid]:
d_min.append(data[i])
d_max.append(data[i+data_mid])
else:
d_max.append(data[i])
d_min.append(data[i+data_mid])
elif ascend == False:
for i in range(data_mid):
if data[i]>data[i+data_mid]:
d_min.append(data[i])
d_max.append(data[i+data_mid])
else:
d_max.append(data[i])
d_min.append(data[i+data_mid])
#d_max.reverse()
d_min = bitonic_to_order(d_min,ascend)
d_max = bitonic_to_order(d_max,ascend)
data_final = d_min+d_max
return data_final
def disorder_to_bitonic(data):
data_num = len(data)
mmm = int(np.log2(data_num))
for i in range(2,mmm):
step = 2**i #2,4,8,
for j in range(0,data_num-step+1,step*2):
data1 = data[j:j+step]
data[j:j+step] = bitonic_to_order(data1,True)
data2 = data[j+step:j+step*2]
data[j+step:j+step*2] = bitonic_to_order(data2,False)
return data
def bitonic_initial(data):
for i in range(0,data_num-3,4):
if data[i]>data[i+1]:
data[i],data[i+1] = data[i+1],data[i]
if data[i+2]<data[i+3]:
data[i+2],data[i+3] = data[i+3],data[i+2]
return data
if __name__ == '__main__':
data = [10,20,50,3,5,7,9,11,88,55,77,56,1,2,4,555]
#data = [ 19, 25, 26, 29 ,38 ,50 ,80, 91 ,86, 78 ,66 ,46, 32 ,19 ,15 , 7]
data_num = len(data)
data = bitonic_initial(data)
data = disorder_to_bitonic(data)
data = bitonic_to_order(data,True)
缺点:一言难尽
answer:
# Python program for Bitonic Sort. Note that this program
# works only when size of input is a power of 2.
# The parameter dir indicates the sorting direction, ASCENDING
# or DESCENDING; if (a[i] > a[j]) agrees with the direction,
# then a[i] and a[j] are interchanged.*/
def compAndSwap(a, i, j, dire):
if (dire == 1 and a[i] > a[j]) or (dire == 0 and a[i] < a[j]):
a[i], a[j] = a[j], a[i]
# It recursively sorts a bitonic sequence in ascending order,
# if dir = 1, and in descending order otherwise (means dir=0).
# The sequence to be sorted starts at index position low,
# the parameter cnt is the number of elements to be sorted.
def bitonicMerge(a, low, cnt, dire):
if cnt > 1:
k = int(cnt / 2)
for i in range(low, low + k):
compAndSwap(a, i, i + k, dire)
bitonicMerge(a, low, k, dire)
bitonicMerge(a, low + k, k, dire)
# This funcion first produces a bitonic sequence by recursively
# sorting its two halves in opposite sorting orders, and then
# calls bitonicMerge to make them in the same order
def bitonicSort(a, low, cnt, dire):
if cnt > 1:
k = int(cnt / 2)
bitonicSort(a, low, k, 1)
bitonicSort(a, low + k, k, 0)
bitonicMerge(a, low, cnt, dire)
# Caller of bitonicSort for sorting the entire array of length N
# in ASCENDING order
def sort(a, N, up):
bitonicSort(a, 0, N, up)
if __name__ == "__main__":
# Driver code to test above
a = []
n = int(input().strip())
for i in range(n):
a.append(int(input().strip()))
up = 1
sort(a, n, up)
print("\n\nSorted array is")
for i in range(n):
print("%d" % a[i])
https://github.com/TheAlgorithms/Python/blob/master/sorts/bitonic_sort.py
递归学习:
https://blog.youkuaiyun.com/khy19940520/article/details/81430850