算法图解 -- 学习笔记(算法简介)

194 阅读3分钟

关键词

  • 二分查找
  • 线性查找
  • 旅行商问题
  • 幂运算
  • 对数
  • 运行时间
  • 大O表示法
  • 常见的大O表示法
  • 算法时间增速

数学知识

以前学的知识都还给老师了,现在重新温故一下。

  • 幂运算

简单理解:幂是指数运算的结果。nᵐ指该式意义为m个n相乘

例如:

2² = 2 * 2 = 4

  • 对数

简单理解:对数是对求幂的逆运算

例如:

 2³ = 8 <=> log₂8 = 3

  • 阶乘

简单理解:所有小于及等于该数的正整数的积

例如:

5! = 5*4*3*2*1 = 120

大O表示法

只是用来表示算法的时间复杂度的名称,无须在意O是什么意思,如果你喜欢,叫X也是可以的。

常见的时间复杂度表示法:

//从低到高
O(log n)
O(n)
O(n * log n)
O(n²)
O(n!)
算法时间复杂度

需要注意的是,算法时间复杂度表示的是算法的时间增速,并不是表示真实的运行时间。可以理解为随着n的增加,时间增长速度是线性增长、还是指数增长,又或是对数增长等。简单理解就是需要查找遍历多少次(步)。

要计算真正的运行时间,假设: 一个数组长度是 n = 8, 每查找一次需要花 2s

//如果是线性查找,那么时间复杂度是
O(n) = O(8) = 8 
// 真正的运行时间是
> 8 * 2 = 16s

//如果是二分查找,那么时间复杂度是
O(log n) = O(log 8) = 3
// 真正的运行时间是
> 3 * 2 = 6s

Tips: 线性查找O(n)不一定比二分查找O(log n)慢,取决于查找数的位置和n的长度, 算法时间复杂度表示的是最坏的情况

练习

func search(guess int, arr []int) (err error, res int, steps int) {
    length      := len(arr)
    low 	:= 0
    high 	:= length - 1
    mid 	:= length / 2
    step 	:= 0
    for ; arr[mid] != guess; {
        step++
        if guess < arr[mid] {
            high = mid - 1
        } else {
            low = mid + 1
        }
        if low > high {
            return nil, -1, step
        }
        mid = (low + high) / 2
    }
    return nil, mid, step
}

func main() {
    arr                 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} 
    _, result1, step1 	:= search(1, arr)
    _, result2, step2 	:= search(2, arr)
    _, result3, step3 	:= search(3, arr)
    _, result4, step4 	:= search(4, arr)
    _, result5, step5 	:= search(5, arr)
    _, result6, step6 	:= search(6, arr)
    _, result7, step7 	:= search(7, arr)
    _, result8, step8 	:= search(8, arr)
    _, result9, step9 	:= search(9, arr)
    _, result19, step19 := search(19, arr)
    
    fmt.Println("1 index ",result1, " step ", step1)
    fmt.Println("2 index ",result2, " step ", step2)
    fmt.Println("3 index ",result3, " step ", step3)
    fmt.Println("4 index ",result4, " step ", step4)
    fmt.Println("5 index ",result5, " step ", step5)
    fmt.Println("6 index ",result6, " step ", step6)
    fmt.Println("7 index ",result7, " step ", step7)
    fmt.Println("8 index ",result8, " step ", step8)
    fmt.Println("9 index ",result9, " step ", step9)
    fmt.Println("19 index ",result19, " step ", step19)
}
// 输出结果
$ go run main.go
1 index  0  step  2
2 index  1  step  1
3 index  2  step  2
4 index  3  step  3
5 index  4  step  0
6 index  5  step  2
7 index  6  step  1
8 index  7  step  2
9 index  8  step  3
19 index  -1  step  4

小结

记得,大学的时候有这门课程的哦!当时我干嘛去了呢?怎么一点印象都没有呢?工作这么多年,也曾有过几次想认真学一次,哎... 这一次,我真的懂了,总算是开了个好头,加油吧!