if arr[j] > arr[j+1] {
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
return arr
}
func main() {
arr1 := []int{33, 8, 12, 7, 6}
arr2 := make([]int, len(arr1))
copy(arr2, arr1)
arr3 := bubbleSort(arr2)
fmt.Printf(“%v=>%v\n”, arr1, arr3) //[33 8 12 7 6]=>[6 7 8 12 33]
fmt.Printf(“%p,%p”, arr1, arr3) //0xc00000e3f0,0xc00000e420
}
另外为了更清晰的表示前后数组(切片)的变化,使用了**copy深拷贝**,这种拷贝可以拷贝里面的值,如果是arr2:=arr1这样的赋值,是一种浅拷贝,也就是说拷贝的是引用,是一个地址,共享同一地址,这样你修改了arr1也会修改arr2
### 冒泡求逆序数
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数
逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。 如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。
那求逆序数的方法通过冒泡来实现就很简单了,也是两个循环,里面循环是第一轮从一个元素开始与后面元素一个一个比较,如果比后面的大就加1做个计数,第二轮从第二个元素开始与后面元素分别一一的去比较,一直这样循环完毕,就把逆序数统计出来了
package main
import “fmt”
func bubbleSort(arr []int) int {
cnt := 0
len := len(arr) - 1
for i := 0; i < len; i++ {
for j := i; j < len; j++ {
if arr[i] > arr[j+1] {
cnt = cnt + 1
}
}
}
return cnt
}
func main() {
arr := []int{5, 3, 6, 2, 1, 4}
arr2 := bubbleSort(arr)
fmt.Printf(“%v的逆序数:%v\n”, arr, arr2)
}
>
> [5 3 6 2 1 4]的逆序数:10
>
>
>
### Go分治法求逆序数
冒泡法虽然简单直观,但是其时间复杂度比较高 :**O(n^2)**。
我们先来看一个快速但比较复杂点的计算方法是在归并排序的同时计算逆序数,采用分治法其时间复杂度为**O(nlogn)** C++版本:[高级排序求逆序数之分治法](https://bbs.csdn.net/topics/618545628) 可以看出分治法其实属于递归变化的一种高级排序。
使用Golang语言来实现,这里我们将使用到切片类型,代码如下:
package main
import (
“fmt”
)
func merge_count(A []int, B []int) (int, []int) {
/*
合并且做了排序并统计逆序数
A列表的值大于B列表的值,就做统计,将B的值(小)添加到C列表
A列表的值小于B列表的值,就将A的值(小)添加到C列表
A和B列表是递归切割出来的
比较剩余之后的值添加到C列表
*/
lenA := len(A)
lenB := len(B)
i := 0
j := 0
rC := 0
var C []int
for i < lenA && j < lenB {
if A[i] > B[j] {
C = append(C, B[j])
j += 1
rC += lenA - i
} else {
C = append(C, A[i])
i += 1
}
}
if i < lenA {
C = append(C, A[i:]…) //切片添加元素需要解包
}
if j < lenB {
C = append(C, B[j:]…)
}
return rC, C
}
func sort_count(L []int) (int, []int) {
/*
递归的切割,然后做合并
*/
if len(L) == 1 {
return 0, L
} else {
rA, A := sort_count(L[0 : len(L)/2])
rB, B := sort_count(L[len(L)/2:])
rC, C := merge_count(A, B) //想明白程序的运行,这里可以做个断点查看
return rA + rB + rC, C
}
}
func main() {
//A := []int{5, 3, 6, 2, 1, 4}
A := []int{11, 5, 3, 6, 2, 9, 1, 4}
fmt.Printf(“%v”, A)
cnt, arr := sort_count(A)
fmt.Printf(“的逆序数:%v,%v”, cnt, arr)
}
>
>
>
> [5 3 6 2 1 4]的逆序数:10,[1 2 3 4 5 6]
>
>
![img](https://img-blog.csdnimg.cn/img_convert/6e992d74b527c4c3ce83912dd3967a76.png)
![img](https://img-blog.csdnimg.cn/img_convert/58639a4b88d31e87ae5e1c26d5f0c846.png)
![img](https://img-blog.csdnimg.cn/img_convert/b08bacd7e3417bda3ad1cf6e4ad5abd0.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**