數據結構和算法(Golang實現)(8.1)基礎知識-前言

基礎知識

學習數據結構和算法。咱們要知道一些基礎的知識。算法

1、什麼是算法

算法(英文algorithm)這個詞在中文裏面博大精深,表示算帳的方法,也能夠表示指揮若定的計謀等。在計算機科技裏,它表示什麼呢?編程

計算機,顧名思義是用來計算的機器。算法在計算機科學中能夠描述爲:計算機接收一個輸入指令,而後進行一個過程處理,最後輸出計算的結果。segmentfault

這種輸入-過程處理-輸出,用人類的行爲模式,很容易理解,好比媽媽讓小明去打醬油,打醬油的命令是輸入,小明發現小區周邊有5家店有醬油出售,娟娟超市是離家最近的,而子龍雜貨店雖然離得最遠,但醬油很便宜。小明爲了省錢,跑到最遠的子龍雜貨店買了醬油,而後順利回到了家,交給了媽媽。買醬油的過程就是處理,而給媽媽的醬油是輸出。

小明爲何不去最近的娟娟超市,而去了最遠的子龍雜貨店,這是小明腦殼裏思考後產生的最佳方案。固然,如今買醬油能夠經過外賣軟件,小明能夠打開美團外賣軟件,搜索關鍵字:醬油,而後點擊篩選,離家最近的和最便宜的,而後選擇最便宜的醬油下單。數組

買醬油的過程 = 美團外賣軟件下單的過程。數據結構

人類在幾千年的演化中,會進行數字運算了,會進行利益權衡了,而後造了機器,將本身的行爲模式,賦予了機器,解放了自身。若是人類真正瞭解人腦神經元的信息傳遞過程,甚至可能造出有自我意識的機器,但這種場景仍然只能在科幻電影中看到。併發

因此,這個邏輯過程,或行爲模式,在計算機裏面映射的是算法。機器學習

用更準確的描述來講:算法是一種有限,肯定,有效的並適合用計算機程序來實現的,用來解決問題的方法。首先,有一個問題,而後有一個方法去解決它,這個方法叫算法。數據結構和算法

算法是有限的,就是算法的步驟是有限的,執行的時間也是有限的,可以在有限時間內得出結果。算法是肯定的,就是不管執行多少次,計算得出的結果都同樣。算法是有效的,就是計算出的結果對解決問題有幫助。編程語言

然而算法的定義一直被刷新,由於機器學習的出現,基於海量超大規模數據,機器學習算法的步驟是無限的,能夠一直計算下去,每次計算的結果也不同,但若是人爲進行步驟限制,以及增長訓練閾值,訓練時得出的參數超過設定的閾值立刻中止運算,倒也符合以上的定義。函數

算法要在有限的時間內完成,自己是對人類的一種負擔,由於人類造出的機器還不夠強。爲何呢?由於即便算法的步驟是有限的,執行的時間也可能特別長。

正如《從一到無窮大》書中印度教聖地貝拿勒斯神廟下的三根寶石針,印度教主神焚天說過,誰能夠把第一根寶石針的64塊金片經過第二根寶石針移到第三根,焚天塔,神廟,婆羅門將化爲灰燼,這是有名的漢諾塔算法。

漢諾塔問題能夠描述爲:

有三根杆(編號A、B、C),在A杆自下而上、由大到小按順序放置64個金盤(以下圖)。遊戲的目標:把A杆上的金盤所有移到C杆上,並仍保持原有順序疊好。

操做規則:每次只能移動一個盤子,而且在移動過程當中三根杆上都始終保持大盤在下,小盤在上,操做過程當中盤子能夠置於A、B、C任一杆上。

咱們很天然想到一個算法:

  1. 咱們必須先借助C杆,將A杆前面N-1個盤子,移動到B杆後,將A杆剩下的一個盤子,直接移動到C杆,這時候A空了。
  2. 而後藉助A杆,將B杆的N-1個盤子,移動到C杆,任務就完成了。

十分樸素的思路,咱們用編程語言來實現:

package main

import "fmt"

var total = 0

// 漢諾塔
// 一開始A杆上有N個盤子,B和C杆都沒有盤子。
func main() {
    n := 4   // 64 個盤子
    a := "a" // 杆子A
    b := "b" // 杆子B
    c := "c" // 杆子C
    tower(n, a, b, c)

    // 當 n=1 時,移動次數爲 1
    // 當 n=2 時,移動次數爲 3
    // 當 n=3 時,移動次數爲 7
    // 當 n=4 時,移動次數爲 15
    fmt.Println(total)
}

// 表示將N個盤子,從 a 杆,藉助 b 杆移到 c 杆
func tower(n int, a, b, c string) {
    if n == 1 {
        total = total + 1
        fmt.Println(a, "->", c)
        return
    }

    tower(n-1, a, c, b)
    total = total + 1
    fmt.Println(a, "->", c)
    tower(n-1, b, a, c)
}

經過概括,咱們能夠知道移動次數Total(N)的關係是Total(N)=2*Total(N-1)+1,每多一個盤子,移動次數就會翻倍加一,咱們經過相關的數列數學方法能夠知道Total(N)=2^N-1,也就是移動次數是一個指數方程:2的N次方,指數等於盤子的數量。

咱們計算出2^64-1=18446744073709551615,能夠知道一我的日夜不停,一秒移動一次:18446744073709551615/3600/24/365/100000000=5849,要5849億年時間才能夠完成這件事,那時候世界確實可能已經毀滅。

在計算機科學中,由於全部的算法都是人定義的規則,規則是死的,因此不要擔憂學不會。當你學會了這些算法,你將會以爲,哇,一切都那麼簡單。

2、什麼是數據結構

數據結構,顧名思義就是存放數據的結構,也能夠認爲是存放數據的容器。好比,你要找出1000個數字中的最大值,首先你要將1000個數字記在某些卡片上,而後對卡片進行排序。

大多數算法都須要組織數據,因此產生了數據結構。數據結構在計算機中,主要是用來實現各類算法的基礎,固然數據結構自己也是算法的一部分。

基本的數據結構有:鏈表,棧和隊列,樹和圖。

鏈表,就是把數據連接起來,關聯起來,一個數據節點指向另一個數據節點,像天然界的一條條鐵鏈,大部分數據結構,都是由鏈表的若干變種來表示。

在每種編程語言中,數組做爲基本數據類型提供,數組是連續的內存存儲空間,經過下標0,1,2能夠迅速獲取到數組指定位置的數據。鏈表也能夠用數組來實現,但通常狀況下,由於數組是連續的,在鏈表增長和刪除節點時容易形成冗餘,效果不佳。因此鏈表在不一樣編程語言實現是這樣的:C、C++是用指針來實現的,Java是用類來實現的,而Golang是用結構體引用來實現。

棧和隊列,主要用來存儲多個數據,只不過一個是先進後出,一個先進先出。好比下壓棧,先入棧的數據是最後才能出來,而咱們熟知的隊列,先排隊的人確定先得到服務。

其次是樹和圖,樹就是有一個樹根節點,存放着數據,下面有不少子節點,也存放着數據,類比天然界的樹。圖則能夠類比天然界的地圖,多個點指向多個點,點和點之間有一條或多條邊,而這些點存放着數據,邊也能夠存放着數據,好比距離等。

圍繞這幾種數據結構,有若干延伸,加上一些排序,查找邏輯,就造成了更高層次的高級數據結構。

數據結構是算法實現的輔助,是爲了更高效組織數據的結構,因此數據結構和算法其實密切聯繫,並不須要分得太清,你們能夠把數據結構等同於算法。

3、什麼叫好的數據結構和好的算法

學習算法的緣由,是好的算法能夠節約資源,可是選擇合適的算法很難。咱們要進行復雜的數學分析才能知道,什麼叫作好的,在計算機裏,咱們把這種數學分析這叫作算法分析。

什麼是好的數據結構和好的算法?

  1. 計算機資源是有限的,因此佔用計算機資源越少的數據結構和算法越好。
  2. 人的生命是有限的的,等待時間是有忍耐度的,因此能輔助程序越快完成工做的數據結構和算法越好。

因此出了個理論:時間和空間算法複雜度理論。

程序執行過程當中,要麼空間換時間,要麼時間換空間,空間能夠認爲是一種計算機資源如內存使用狀況,而時間是人類感知的第四個維度,就是慢仍是快,二者通常不能兼得,若是發現竟然兼得了,那就是發明了一種更好的算法。

在計算機科學發展的四五十年,這種既省資源又省時間的發明仍是比較少的,好比數據壓縮算法,由於發明了超高效的無損數據壓縮算法,咱們網上看視頻的時候,既不失真,也不卡頓,又快又好,這種就叫好算法。

目前有一種新型的計算方式正在研究中,叫量子計算,能夠在很是小的空間,使用很是少的資源,短期內計算超級大量的數據,讓咱們期待能成功量產的那天,到了那時候,人類生產力將極大被解放。

4、總結

程序設計在通常程度上,不少人都認爲=數據結構+算法。

咱們學習數據結構和算法,是爲了更高效率寫出更快,更好的代碼。

由於學習過,因此咱們不須要從零開始設計,工做效率就提升了。

由於知道每種數據結構和算法的複雜度和適用場景,自由選擇組合,咱們寫出的代碼計算速度變快了,佔用的資源更少了。

因此咱們要好好學習和理解常見的數據結構和算法。

歡迎閱讀剩下的章節。

系列文章入口

我是陳星星,歡迎閱讀我親自寫的 數據結構和算法(Golang實現),文章首發於 閱讀更友好的GitBook

相關文章
相關標籤/搜索