文章目录
- 奇偶转置排序的核心思想: 在 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)
目录
- 一、项目背景详细介绍
- 二、项目需求详细介绍
- 功能要求
- 三、相关技术详细介绍
- 什么是奇偶转置排序?
- 与普通奇偶排序区别
- 算法示例
- 时间复杂度
- 四、实现思路详细介绍
- 核心思路
- 五、完整实现代码
- 六、代码详细解读(仅解读方法作用)
- OddEvenTranspositionSort
- OddEvenTranspositionSortGeneric
- OddEvenTranspositionSortParallel
- 七、项目详细总结
- 八、项目常见问题及解答
- Q1:与奇偶排序一样吗?
- Q2:是否稳定排序?
- Q3:为什么适合并行?
- Q4:时间复杂度是多少?
- Q5:生产环境使用吗?
- 九、扩展方向与性能优化
- 使用 atomic 修复并发竞争
- 实现排序网络可视化
- GPU版本实现
- MPI分布式版本
- 与快速排序混合实现
- 总结
在排序算法体系中,除了我们熟悉的:
-
冒泡排序(Bubble Sort)
-
插入排序(Insertion Sort)
-
选择排序(Selection Sort)
-
快速排序(Quick Sort)
-
归并排序(Merge Sort)
还存在一类专门为并行计算环境设计的排序算法。
其中一个经典算法就是:
奇偶转置排序(Odd-Even Transposition Sort)
它也被称为:
-
Brick Sort
-
Parallel Bubble Sort
该算法特别适用于:
-
多核CPU并行计算
-
分布式排序
-
GPU排序
-
MPI并行环境
-
排序网络教学
在理论上,它属于:
冒泡排序的并行改进版本
虽然时间复杂度仍然是 O(n²),但其阶段结构非常适合并行化。
-
实现整数数组奇偶转置排序
-
支持升序排序
-
提供泛型版本(Go 1.18+)
-
提供并发优化版本
-
代码完整可运行
-
所有代码放在一个代码块内
-
包含详细注释
-
提供完整测试代码
实现整数数组奇偶转置排序
支持升序排序
提供泛型版本(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)
最坏: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
// ==========================================
// 文件名:main.go
// ==========================================
package main
import (
"fmt"
"sync"
)
// ==========================================
// 基础奇偶转置排序(整数版本)
// ==========================================
// OddEvenTranspositionSort 实现奇偶转置排序
func OddEvenTranspositionSort(arr []int) {
n := len(arr)
// 固定执行 n 轮
for phase := 0; phase < n; phase++ {
// 偶数阶段
if phase%2 == 0 {
for i := 0; i < n-1; i += 2 {
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
} else { // 奇数阶段
for i := 1; i < n-1; i += 2 {
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
}
}
}
// ==========================================
// 泛型版本(Go 1.18+)
// ==========================================
type Ordered interface {
~int | ~int64 | ~float64 | ~string
}
// OddEvenTranspositionSortGeneric 泛型实现
func OddEvenTranspositionSortGeneric[T Ordered](arr []T) {
n := len(arr)
for phase := 0; phase < n; phase++ {
if phase%2 == 0 {
for i := 0; i < n-1; i += 2 {
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
} else {
for i := 1; i < n-1; i += 2 {
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
}
}
}
// ==========================================
// 并发版本(教学演示)
// ==========================================
// OddEvenTranspositionSortParallel 并发实现
func OddEvenTranspositionSortParallel(arr []int) {
n := len(arr)
for phase := 0; phase < n; phase++ {
var wg sync.WaitGroup
if phase%2 == 0 {
for i := 0; i < n-1; i += 2 {
wg.Add(1)
go func(i int) {
defer wg.Done()
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}(i)
}
} else {
for i := 1; i < n-1; i += 2 {
wg.Add(1)
go func(i int) {
defer wg.Done()
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}(i)
}
}
wg.Wait()
}
}
// ==========================================
// 测试代码
// ==========================================
func main() {
// 基础测试
arr := []int{5, 3, 8, 4, 2, 7, 1}
fmt.Println("排序前:", arr)
OddEvenTranspositionSort(arr)
fmt.Println("排序后:", arr)
// 泛型测试
strArr := []string{"banana", "apple", "orange", "grape"}
fmt.Println("n字符串排序前:", strArr)
OddEvenTranspositionSortGeneric(strArr)
fmt.Println("字符串排序后:", strArr)
// 并发版本测试
arr2 := []int{9, 4, 6, 2, 8, 1}
fmt.Println("n并发排序前:", arr2)
OddEvenTranspositionSortParallel(arr2)
fmt.Println("并发排序后:", arr2)
}
-
固定执行 n 轮
-
每轮根据 phase 判断奇偶阶段
-
比较相邻元素并交换
固定执行 n 轮
每轮根据 phase 判断奇偶阶段
比较相邻元素并交换
-
使用 Go 泛型
-
支持 int、float、string
-
提高复用性
使用 Go 泛型
支持 int、float、string
提高复用性
-
每对比较使用 goroutine
-
使用 WaitGroup 同步
-
教学展示并行排序思想
每对比较使用 goroutine
使用 WaitGroup 同步
教学展示并行排序思想
⚠️ 注意:
该版本可能存在数据竞争问题,在生产环境需加锁或使用原子操作。
本项目实现了:
-
奇偶转置排序原理
-
基础版本
-
泛型版本
-
并发版本
-
教学级代码结构
优点:
-
实现简单
-
易理解
-
适合并行
-
排序网络经典算法
缺点:
-
时间复杂度高
-
不适合大规模数据
逻辑相似,但奇偶转置排序固定执行 n 轮。
是稳定排序。
同一阶段的比较对互不影响。
O(n²)
一般不用于大数据排序。
通过本篇文章,你掌握了:
-
奇偶转置排序原理
-
并行排序思想
-
Go泛型排序实现
-
固定轮次排序结构
奇偶转置排序是:
并行排序网络的经典算法
理解它,就真正理解了:
-
并行排序的阶段模型
-
相邻交换排序机制
-
排序网络基础结构
这是深入学习并行计算与高性能算法的重要一步。
到此这篇关于go语言奇偶转置排序算法实现方法的文章就介绍到这了,更多相关go语言奇偶转置排序算法内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- Go用两个协程交替打印100以内的奇偶数的方法详解