双调排序的Python程序
双调序列
如果一个序列首先增加,然后减少,则称为双调。换句话说,如果存在索引 i 其中 0<=i<=n-1 使得数组 arr[0..ni] 是双调的
x0 <= x1 …..<= xi and xi >= xi+1….. >= xn-1
- 一个按升序排序的序列被认为是双调的,降序部分为空。类似地,降序序列被认为是双调,增加的部分为空。
- 双调序列的旋转也是双调的。
双调排序
它主要包括两个步骤。
- 形成一个双音序列(上面详细讨论过)。经过这一步我们到了下图中的第四阶段,即数组变为{3, 4, 7, 8, 6, 5, 2, 1}
- 从双音序列创建一个排序序列:第一步后,前半部分按升序排序,后半部分按降序排序。
我们将前半部分的第一个元素与后半部分的第一个元素进行比较,然后将前半部分的第二个元素与后半部分的第二个元素进行比较,依此类推。如果前半部分的元素较小,我们交换元素。
经过上述比较和交换步骤,我们得到了数组中的两个双音序列。见下图中的第五阶段。在第五阶段,我们有 {3, 4, 2, 1, 6, 5, 7, 8}。如果我们仔细观察元素,我们可以注意到有两个长度为 n/2 的双音序列,使得第一个双音序列 {3,4,2,1} 中的所有元素都小于第二个双音序列的所有元素{6、5、7、8}。
我们在两个双音序列中重复相同的过程,我们得到四个长度为 n/4 的双音序列,使得最左边的双音序列的所有元素都更小,而最右边的所有元素都更小。见下图中的第六阶段,数组是 {2, 1, 3, 4, 6, 5, 7, 8}。
如果我们再重复一次这个过程,我们会得到 8 个大小为 n/8 的双音序列,即 1。由于所有这些双音序列都是排序的,并且每个双音序列都有一个元素,因此我们得到了排序后的数组。
Python3
# 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 = 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 function 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 = 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)
# Driver code to test above
a = [3, 7, 4, 8, 6, 2, 1, 5]
n = len(a)
up = 1
sort(a, n, up)
print ("\n\nSorted array is")
for i in range(n):
print("%d" %a[i],end=" ")
输出:
Sorted array is
1 5 2 6 3 7 4 8
有关详细信息,请参阅有关双音排序的完整文章!