背景
在排序算法体系中,除了我们熟悉的冒泡排序、插入排序、选择排序、快速排序、归并排序外,还存在一类专门为并行计算环境设计的排序算法。其中一个经典算法就是奇偶转置排序(Odd-Even Transposition Sort),也被称为 Brick Sort 或 Parallel Bubble Sort。
该算法特别适用于多核 CPU 并行计算、分布式排序、GPU 排序、MPI 并行环境及排序网络教学。在理论上,它属于冒泡排序的并行改进版本。虽然时间复杂度仍然是 O(n²),但其阶段结构非常适合并行化。
需求
- 实现整数数组奇偶转置排序
- 支持升序排序
- 提供泛型版本(Go 1.18+)
- 提供并发优化版本
- 代码完整可运行
- 包含详细注释
- 提供完整测试代码
技术原理
什么是奇偶转置排序?
奇偶转置排序的核心思想是在 n 轮迭代中,交替执行'奇数索引比较'和'偶数索引比较'。
算法步骤:
- 第 0 轮:比较 (0,1), (2,3), (4,5)...
- 第 1 轮:比较 (1,2), (3,4), (5,6)...
- 第 2 轮:比较 (0,1), (2,3), (4,5)...
- ...
- 总共执行 n 轮
关键点:
- 每轮的比较可以并行执行
- 一共需要 n 轮
- 保证排序完成
与普通奇偶排序区别
| 对比项 | 奇偶排序 | 奇偶转置排序 |
|---|---|---|
| 终止条件 | 无交换即停止 | 固定执行 n 轮 |
| 轮次数量 | 不确定 | 固定 n 轮 |
| 更适合并行 | 是 | 更适合 |
| 算法结构 | while 循环 | for 固定轮次 |
算法示例
假设数组:[5, 3, 8, 4, 2]
第一轮(偶数阶段):(0,1), (2,3) 第二轮(奇数阶段):(1,2), (3,4) 不断执行共 n 轮。
时间复杂度
- 最坏:O(n²)
- 平均:O(n²)
- 空间复杂度:O(1)
实现思路
设数组长度为 n:
for i := 0; i < n; i++ {
if i%2 == 0:
执行偶数阶段
else:
执行奇数阶段
}
偶数阶段:for j := 0; j < n-1; j += 2
奇数阶段:for j := 1; j < n-1; j += 2
代码实现
package main
import (
)
{
n := (arr)
phase := ; phase < n; phase++ {
phase% == {
i := ; i < n; i += {
arr[i] > arr[i+] {
arr[i], arr[i+] = arr[i+], arr[i]
}
}
} {
i := ; i < n; i += {
arr[i] > arr[i+] {
arr[i], arr[i+] = arr[i+], arr[i]
}
}
}
}
}
Ordered {
~ | ~ | ~ | ~
}
{
n := (arr)
phase := ; phase < n; phase++ {
phase% == {
i := ; i < n; i += {
arr[i] > arr[i+] {
arr[i], arr[i+] = arr[i+], arr[i]
}
}
} {
i := ; i < n; i += {
arr[i] > arr[i+] {
arr[i], arr[i+] = arr[i+], arr[i]
}
}
}
}
}
{
n := (arr)
phase := ; phase < n; phase++ {
wg sync.WaitGroup
phase% == {
i := ; i < n; i += {
wg.Add()
{
wg.Done()
arr[i] > arr[i+] {
arr[i], arr[i+] = arr[i+], arr[i]
}
}(i)
}
} {
i := ; i < n; i += {
wg.Add()
{
wg.Done()
arr[i] > arr[i+] {
arr[i], arr[i+] = arr[i+], arr[i]
}
}(i)
}
}
wg.Wait()
}
}
{
arr := []{, , , , , , }
fmt.Println(, arr)
OddEvenTranspositionSort(arr)
fmt.Println(, arr)
strArr := []{, , , }
fmt.Println(, strArr)
OddEvenTranspositionSortGeneric(strArr)
fmt.Println(, strArr)
arr2 := []{, , , , , }
fmt.Println(, arr2)
OddEvenTranspositionSortParallel(arr2)
fmt.Println(, arr2)
}

