
0 大纲

基本算法的复杂度:

1 基本概念
稳定性

时间复杂度
**时间复杂度:**用来衡量随着算法规模的扩大,算法执行时间增长的快慢。
**常见时间复杂度:**O(1)<O(log n)<O(nlog n)<O(n^2)<O(n^3)<O(2^n)
长用计算方法:
- 单个循环直接关注循环次数
- 多个循环:内循环-乘法规则,外循环-加法规则
空间复杂度
**空间复杂度:**算法执行过程中所使用辅助空间的大小
**常见时间复杂度:**一般为O(1),O(logn),O(n)
2 冒泡排序
时间复杂度:O(n^2)——两个循环嵌套
空间复杂度:O(1)——基本操作在于交换两个数据
稳定性:稳定
//Mpsort 冒泡算法
func Mpsort(arr []int) {
l := len(arr)
for i := 0; i < l; i++ {
for j := 0; j < l-i-1; j++ {
if arr[j] > arr[j+1] {
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
}
3 快速排序
时间复杂度:O(nlogn)
空间复杂度:O(nlogn)——递归调用
稳定性:不稳定
//Ksort 快排
func Ksort(arr []int) {
l := len(arr)
if l < 2 {
return
}
temp := arr[0]
i, j := 0, l-1
for i < j {
for arr[j] > temp && i < j {
j--
}
arr[i] = arr[j]
for arr[i] < temp && i < j {
i++
}
arr[j] = arr[i]
}
arr[i] = temp
Ksort(arr[0:i])
Ksort(arr[i+1 : l])
}
4 简单选择排序
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定
//Xzsort 选择排序
func Xzsort(arr []int) {
l := len(arr)
for i := 0; i < l-1; i++ {
min := i
for j := i + 1; j < l; j++ {
if arr[j] < arr[min] {
min = j
}
}
if min != i {
arr[i], arr[min] = arr[min], arr[i]
}
}
}
5 堆排序
时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:不稳定
//Heapsort 堆排序
func Heapsort(arr []int) {
//生成最小堆
l := len(arr)
for i := (l - 1) / 2; i >= 0; i-- {
downadjust(arr, i, l-1)
}
//进行排序
for i := l - 1; i > 0; i-- {
arr[i], arr[0] = arr[0], arr[i]
downadjust(arr, 0, i-1)
}
}
//downadjust 向下调整
func downadjust(arr []int, root int, end int) {
temp := arr[root]
child := root*2 + 1
for child <= end {
if child+1 <= end && arr[child] < arr[child+1] {
child = child + 1
}
if arr[child] < temp {
break
}
arr[root] = arr[child]
root = child
child = 2*root + 1
}
arr[root] = temp
}
6 直接插入排序
时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:不稳定
//Crsort 插入排序
func Crsort(arr []int) {
l := len(arr)
var temp int
tag := 0
for i := 1; i < l; i++ {
tag = 0
temp = arr[i]
for j := i - 1; j >= 0; j-- {
if temp > arr[j] {
arr[j+1] = temp
tag = 1
break
}
arr[j+1] = arr[j]
}
if tag == 0 {
arr[0] = temp
}
}
}
7 折半插入排序
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定
//Zbcrsort 折半插入排序
func Zbcrsort(arr []int) {
l := len(arr)
var (
temp int
p int
)
for i := 1; i < l; i++ {
temp = arr[i]
//找到插入位置p
p = insertplace(arr, 0, i-1, i)
//排序
for j := i; j > p; j-- {
arr[j] = arr[j-1]
}
arr[p] = temp
}
}
//insertplace 检索插入点
func insertplace(arr []int, start int, end int, current int) int {
if start >= end {
if arr[start] < arr[current] {
return current
}
return start
}
mid := start + (end-start)/2
if arr[mid] > arr[current] {
return insertplace(arr, 0, mid, current)
}
return insertplace(arr, mid+1, end, current)
}
8 希尔排序
时间复杂度:O(n^1.3)
空间复杂度:O(1)
稳定性:不稳定
//Xesort 希尔排序
func Xesort(arr []int) {
l := len(arr)
step := l / 2
for step > 0 {
for i := 0; i < l; i++ {
j := i
for j-step >= 0 && arr[j-step] > arr[j] {
arr[j-step], arr[j] = arr[j], arr[j-step]
j -= step
}
}
step /= 2
}
}
9 归并排序
时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:稳定
//Gbsort 归并排序
func Gbsort(arr []int) []int {
l := len(arr)
if l < 2 {
return arr
}
mid := l / 2
left := Gbsort(arr[0:mid])
right := Gbsort(arr[mid:l])
ans := merge2(left, right)
return ans
}
//merge2 合并
func merge2(left []int, right []int) []int {
ll, lr := len(left), len(right)
i, j := 0, 0
ans := []int{}
for i < ll && j < lr {
if left[i] < right[j] {
ans = append(ans, left[i])
i++
} else {
ans = append(ans, right[j])
j++
}
}
ans = append(ans, left[i:]...)
ans = append(ans, right[j:]...)
return ans
}
10 计数排序
时间复杂度:O(n+k)
空间复杂度:O(k)
稳定性:稳定
//Jssort 计数排序
func Jssort(arr []int, maxvalue int) {
//定义一个最大值+1长的数组,用于分类存放
bucket := make([]int, maxvalue+1)
l := len(arr)
sortedindex := 0
//存放到相应位置上
for i := 0; i < l; i++ {
bucket[arr[i]] = bucket[arr[i]] + 1
}
//依次取出放回原数组
for i := 0; i < maxvalue+1; i++ {
for bucket[i] > 0 {
arr[sortedindex] = i //注意这里放的是i
sortedindex++
bucket[i]--
}
}
}