數(shù)據(jù)結(jié)構(gòu)小結(jié)

數(shù)組

  • 數(shù)組是一種非常常見的線性數(shù)據(jù)結(jié)構(gòu)
  • 它最大的特點(diǎn)是使用一組連續(xù)的內(nèi)存空間,存儲(chǔ)一組相同類型的數(shù)據(jù):
數(shù)組的存儲(chǔ)形式.jpg
  • 之所以強(qiáng)調(diào)相同類型盏筐,是因?yàn)橄嗤念愋偷臄?shù)據(jù)會(huì)占據(jù)相等的存儲(chǔ)空間琢融,因此就可以通過(guò)計(jì)算直接獲取內(nèi)存地址吏奸。
  • 優(yōu)點(diǎn):數(shù)組最大的特性,是支持隨機(jī)訪問烈钞,即可以通過(guò)索引直接訪問某個(gè)數(shù)據(jù)
  • 數(shù)組的訪問性能非常高毯欣,還有一個(gè)原因是在硬件層面有CPU的高速緩存(cache)提升性能
  • 缺點(diǎn):數(shù)組的添加酗钞、刪除的性能很低砚作,因?yàn)闀?huì)涉及大量的數(shù)據(jù)搬移工作嘹锁。
  • 所以你會(huì)發(fā)現(xiàn)领猾,go 中給數(shù)組和切片的操作很少,低性能可能是其中的原因之一
  • 這也是為什么 go 中指定 slice 長(zhǎng)度可以提升性能(減少追加數(shù)據(jù)時(shí)的數(shù)據(jù)搬移工作)

鏈表

  • 鏈表是另一種非成傩ⅲ基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)韭山,與數(shù)組不同钱磅,它使用零散的內(nèi)存存儲(chǔ)數(shù)據(jù):
數(shù)組和鏈表的存儲(chǔ).jpg

單鏈表.jpg
  • 由于它的存儲(chǔ)方式和數(shù)組完全不同,所以它和數(shù)組的特性完全不同:
  • 優(yōu)點(diǎn):高效的插入和刪除
鏈表的插入和刪除.jpg
  • 缺點(diǎn):鏈表的查找非常低效褪迟,只能依次遍歷所有節(jié)點(diǎn)
  • 在 go 中味赃,container 包里有雙向鏈表心俗、雙向循環(huán)鏈表等容器供我們使用城榛,下面是鏈表的部分方法:
func (l *List) MoveBefore(e, mark *Element)
func (l *List) MoveAfter(e, mark *Element)

func (l *List) MoveToFront(e *Element)
func (l *List) MoveToBack(e *Element)

func (l *List) Front() *Element
func (l *List) Back() *Element

func (l *List) InsertBefore(v interface{}, mark *Element) *Element
func (l *List) InsertAfter(v interface{}, mark *Element) *Element

func (l *List) PushFront(v interface{}) *Element
func (l *List) PushBack(v interface{}) *Element
  • 單純的鏈表在實(shí)際編程中很少用到狠持,但是如果我們對(duì)鏈表進(jìn)行升級(jí)喘垂,給一些額外的結(jié)構(gòu)正勒,它就會(huì)有非常廣泛的應(yīng)用楚午。
  • 簡(jiǎn)單的變型有:雙向鏈表矾柜、循環(huán)鏈表等,復(fù)雜的變型有:紅黑樹丧荐、B+樹等虹统。這種變型非常重要车荔,其中就包括 redis 中實(shí)現(xiàn) zset 的跳表:
跳表-二級(jí)索引.jpg

  • 一種操作受到限制的線性表忧便,最大的特點(diǎn)是后進(jìn)先出
  • 椫樵觯可以用數(shù)組或者鏈表實(shí)現(xiàn)
  • 棧只有兩種操作:入棧和出棧
棧.jpg
  • 特定的數(shù)據(jù)結(jié)構(gòu)是特定使用場(chǎng)景的抽象
  • 對(duì)于棧來(lái)說(shuō),主要的使用場(chǎng)景有:括號(hào)匹配凝垛,算數(shù)運(yùn)算苔严,瀏覽器的前進(jìn)后退功能等
  • 當(dāng)然,最常見的還是編程中的函數(shù)調(diào)用棧:
def sum(a,b):
    return a + b

if __name__ == '__main__':
    print(sum(1,2))

下面的圖片展示了這個(gè)程序執(zhí)行的過(guò)程:


函數(shù)調(diào)用棧覆旭,省略了變量名

隊(duì)列

  • 隊(duì)列也是一種操作受限的線性表型将,它的特性是先進(jìn)先出
棧和隊(duì)列.jpg
  • 隊(duì)列也只有兩種主要操作:從隊(duì)尾入隊(duì)和從隊(duì)首出隊(duì)
  • 隊(duì)列也可以有變型:循環(huán)隊(duì)列、阻塞隊(duì)列等:
循環(huán)隊(duì)列.jpg

阻塞隊(duì)列.jpg
  • 隊(duì)列可以非常方便地實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模型腕铸,應(yīng)用有消息隊(duì)列中間件狠裹。

散列表(哈希表)

  • 散列表依賴于數(shù)組支持依照下標(biāo)隨機(jī)訪問的特性
  • 散列表由三個(gè)部分組成:鍵涛菠、散列函數(shù) 和 散列值俗冻。這個(gè)的過(guò)程是迄薄,鍵通過(guò)散列函數(shù)的計(jì)算得到散列值噪奄,然后去尋找這個(gè)值代表的響應(yīng)的地址:
散列
  • 非常常見的一個(gè)問題是勤篮,如果多個(gè)鍵的散列值相同(散列沖突)都毒,該怎么辦?常見的解決辦法有兩種:
  1. 開放尋址法:
散列沖突-開放尋址法.jpg
  1. 鏈表法
散列沖突-鏈表法.jpg
  • 上面的方法都是最基礎(chǔ)的解決方法碰缔,實(shí)際上账劲,根據(jù)場(chǎng)景的不同,會(huì)有很多種解決方案金抡。例如瀑焦,將鏈表法后接的鏈表設(shè)計(jì)成紅黑樹,可以防止哈希碰撞攻擊榛瓮。
  • 你會(huì)發(fā)現(xiàn),數(shù)據(jù)結(jié)構(gòu)的使用不是孤立的巫击,多種數(shù)據(jù)結(jié)構(gòu)的組合禀晓,會(huì)有超乎想象的結(jié)果。
    在這些組合中坝锰,哈希+鏈表就是一個(gè)包打天下的萬(wàn)金油組合粹懒,redis中的zset就是這樣。

  • 樹是一種非線性表結(jié)構(gòu)顷级,可以用于表示一對(duì)多的關(guān)系:
  • 樹中有一些概念用于描述這個(gè)結(jié)構(gòu):


    樹的描述
  • 樹有很多類型凫乖,其中最簡(jiǎn)單的是二叉樹,因?yàn)槎鏄涞男再|(zhì)簡(jiǎn)單,且方便存儲(chǔ)帽芽。
  • 樹有很多應(yīng)用删掀,其中就有大家最為熟知的B+樹:
B+樹
  • 還有一種比較有意思的應(yīng)用:Trie樹,這個(gè)數(shù)據(jù)結(jié)構(gòu)可以幫助我們實(shí)現(xiàn)關(guān)鍵詞提示功能:


    搜索關(guān)鍵詞提示

Trie樹的結(jié)構(gòu)是這樣的:

Trie樹

在這個(gè)樹中嚣镜,存儲(chǔ)了“hello”爬迟、“her”、“hi”菊匿、“how”付呕、“see”、“so” 幾個(gè)查找關(guān)鍵字跌捆,當(dāng)用戶輸入一個(gè)特定字符的時(shí)候徽职,Trie樹會(huì)搜索相關(guān)的節(jié)點(diǎn),并遍歷到樹的葉子節(jié)點(diǎn)佩厚,途徑的所有路徑都會(huì)被記錄下來(lái)姆钉,用于關(guān)鍵字提示:


Trie樹搜索

實(shí)際上,輸入法的自動(dòng)補(bǔ)全抄瓦,IDE的代碼的自動(dòng)補(bǔ)全潮瓶,瀏覽器網(wǎng)址輸入的自動(dòng)補(bǔ)全,都使用了這種數(shù)據(jù)結(jié)構(gòu)钙姊。

  • 圖用于表示一種多對(duì)多關(guān)系
  • 多對(duì)多的關(guān)系很比較復(fù)雜毯辅,所以圖的種類也比較多,大體來(lái)說(shuō)有無(wú)向圖煞额、有向圖思恐、帶權(quán)圖等
有向圖.jpg

帶權(quán)圖.jpg
  • 圖有兩種存儲(chǔ)方法:使用鄰接矩陣 和 使用鄰接表
圖存儲(chǔ)-鄰接矩陣.jpg
  • 臨接矩陣的優(yōu)點(diǎn):存儲(chǔ)方式簡(jiǎn)單、直接膊毁,可以高效地獲取兩個(gè)點(diǎn)之間的關(guān)系
  • 缺點(diǎn):
    1胀莹、如果是無(wú)向圖,鄰接矩陣是關(guān)于主軸對(duì)稱的婚温,這會(huì)浪費(fèi)一般的空間
    2描焰、如果各個(gè)點(diǎn)之間的關(guān)聯(lián)非常稀疏,使用鄰接矩陣會(huì)浪費(fèi)大量空間栅螟。例如微信的好友關(guān)系
圖存儲(chǔ)-鄰接表.jpg
  • 優(yōu)點(diǎn)
    1栈顷、比較節(jié)省存儲(chǔ)空間
    2、你可以根據(jù)業(yè)務(wù)場(chǎng)景改造鄰接表嵌巷,以提升特定場(chǎng)景下的性能。例如將鏈表改造成紅黑樹室抽。

  • 缺點(diǎn)
    1搪哪、對(duì)緩存不友好
    2、鄰接表的查找比鄰接矩陣更加耗時(shí)
    3坪圾、如果存儲(chǔ)的圖是有向圖晓折,又要統(tǒng)計(jì)點(diǎn)的出度和入度惑朦,需要添加逆鄰接表

  • 圖的應(yīng)用非常廣泛,如保存好友關(guān)系漓概、最短路徑規(guī)劃等

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末漾月,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子胃珍,更是在濱河造成了極大的恐慌梁肿,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件觅彰,死亡現(xiàn)場(chǎng)離奇詭異吩蔑,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)填抬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門烛芬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人飒责,你說(shuō)我怎么就攤上這事赘娄。” “怎么了宏蛉?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵遣臼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我檐晕,道長(zhǎng)暑诸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任辟灰,我火速辦了婚禮个榕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘芥喇。我一直安慰自己西采,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布继控。 她就那樣靜靜地躺著械馆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪武通。 梳的紋絲不亂的頭發(fā)上霹崎,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音冶忱,去河邊找鬼尾菇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的派诬。 我是一名探鬼主播劳淆,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼默赂!你這毒婦竟也來(lái)了沛鸵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缆八,失蹤者是張志新(化名)和其女友劉穎曲掰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耀里,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜈缤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冯挎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片底哥。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖房官,靈堂內(nèi)的尸體忽然破棺而出趾徽,到底是詐尸還是另有隱情,我是刑警寧澤翰守,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布孵奶,位于F島的核電站,受9級(jí)特大地震影響蜡峰,放射性物質(zhì)發(fā)生泄漏了袁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一湿颅、第九天 我趴在偏房一處隱蔽的房頂上張望载绿。 院中可真熱鬧,春花似錦油航、人聲如沸崭庸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)怕享。三九已至,卻和暖如春镰踏,著一層夾襖步出監(jiān)牢的瞬間函筋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工奠伪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驻呐,地道東北人灌诅。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像含末,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子即舌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容