冒泡排序
算法原理:按照从左至右(或从右至左)顺序依次对相邻两元素进行比较和排序,较大数据往下沉,较小数据向上冒泡.
时间复杂度: O( n 2 n^2 n2)
-
普通方法实现
/** go默认值传递,所以此处需要使用指针修改原数组 */ func bubbleSort(arr *[6]int) [6]int{ n := len(*arr) for i:=0;i<n;i++ { // 每一轮确定一个最大值 for j:=1;j<n-i;j++ { // 每一轮过后有i个元素被排好序 if (*arr)[j-1] > (*arr)[j] { tmp := (*arr)[j-1] (*arr)[j-1] = (*arr)[j] (*arr)[j] = tmp } } } return *arr }
-
改进算法1
/**
* 添加一个exchange标志,如果未发生交换这说明数据已经排好序无需后续比较
*/
func bubbleSort2(arr *[6]int) [6]int {
n := len(arr)
for i := 0; i < n; i++ {
exchange := false
for j := 1; j < n-i; j++ {
if (*arr)[j-1] > (*arr)[j] { // 每一轮过后有i个元素被排好序
tmp := (*arr)[j-1]
(*arr)[j-1] = (*arr)[j]
(*arr)[j] = tmp
exchange = true
}
}
if !exchange {
break
}
fmt.Printf("第%d轮排序结果:%v\n", (i+1), *arr)
}
return *arr
}
- 改进算法2
/**
* 设置pos指针,pos后面的数据不用再参与排序
*/
func bubbleSort3(arr *[6]int) [6]int{
counter := 1
endPoint := len(arr) - 1
for endPoint > 0 {
pos := 1
for j:=1;j<=endPoint;j++ {
if (*arr)[j-1] > (*arr)[j] { // 每一轮过后有i个元素被排好序
tmp := (*arr)[j-1]
(*arr)[j-1] = (*arr)[j]
(*arr)[j] = tmp
pos = j; // 第j个元素发生交换
}
}
endPoint = pos - 1
fmt.Printf("第%d轮排序结果:%v\n", counter, *arr)
counter++
}
return *arr
}
选择排序
算法原理:第一次循环选出最大值与数组第一个元素交换,第二次循环选出第二大元素与数组第二个元素交换…依次类推。
时间复杂度: O( n 2 n^2 n2);
func selectSort(arr *[6]int) [6]int {
n := len(arr)
for i := 0; i < n-1; i++ {
minPoint := i
for j := i + 1; j < n; j++ {
if (*arr)[j] < (*arr)[minPoint] {
minPoint = j
}
}
if minPoint != i {
tmp := (*arr)[i]
(*arr)[i] = (*arr)[minPoint]
(*arr)[minPoint] = tmp
}
fmt.Printf("第%d轮排序结果:%v\n", (i+1), *arr)
}
return *arr
}
插入排序
算法原理:假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数找到相应位置并插入。
时间复杂度: O( n 2 n^2 n2);
- 代码实现
func insertSort(arr *[6]int) [6]int {
n := len(arr)
for i:=1;i<n-1;i++ {
tmp := arr[i]
insertPoint := i - 1
for insertPoint >= 0 && (*arr)[insertPoint] > tmp {
(*arr)[insertPoint + 1] = (*arr)[insertPoint]
insertPoint--
}
(*arr)[insertPoint + 1] = tmp // 确认好插入位置后替换对应的值
fmt.Printf("第%d轮排序结果:%v\n", i, *arr)
}
return *arr
}
归并排序
算法原理: 采用分而治之的思想,不停对数组进行拆分,最后再合并两个数组,最终返回合并后的结果
时间复杂度: O( n ∗ log 2 3 n*\log_{2}{3} n∗log23)
func mergeSort(arr *[6]int, low int, high int) {
if low == high {
return
} else {
mid := (low + high) / 2
mergeSort(arr, low, mid)
mergeSort(arr, mid+1, high)
merge(arr, low, mid, high)
}
}
func merge(a *[6]int, low int, mid int, high int) {
count := high - low + 1
workSpace := make([]int, count)
// 注意:low的值后面会使用,所以采用更新临时变量方式
l, h, m, n := low, high, mid, mid+1
j := 0
for l <= mid && n <= h {
if (*a)[l] <= (*a)[n] {
// 注意数组不能j++,测试使用报错
workSpace[j] = (*a)[l]
j++
l++
} else {
workSpace[j] = (*a)[n]
j++
n++
}
}
for l <= m {
workSpace[j] = (*a)[l]
j++
l++
}
for n <= h {
workSpace[j] = (*a)[n]
j++
n++
}
fmt.Printf("workSpqce值:%v\n", workSpace)
for j := 0; j < count; j++ {
(*a)[low] = workSpace[j]
low++
}
}
快速排序
算法原理:选取一个基准值,不停把数组左边分为比基准值小的元素,右边分为比基准值大的元素,最终实现数组的排序.
时间复杂度: O( n ∗ log 2 3 n*\log_{2}{3} n∗log23)
func quickSort(arr *[6]int, low int, high int) {
if low >= high {
return
} else {
temp := arr[low]
partition := partition(arr, low, high, temp)
quickSort(arr, low, partition)
quickSort(arr, partition+1, high)
}
}
func partition(arr *[6]int, low int, high int, temp int) int {
l, h := low, high
for l < h {
// 右边找到第一个比基准值小的元素
for l < h && (*arr)[h] >= temp {
h--
}
// 左边找到第一个比基准值大的元素
for l < h && (*arr)[l] <= temp {
l++
}
// 交换位置
swap(arr, l, h)
}
(*arr)[low] = (*arr)[l]
(*arr)[l] = temp
return l
}
func swap(arr *[6]int, i int, j int) {
temp := (*arr)[i]
(*arr)[i] = (*arr)[j]
(*arr)[j] = temp
}