你必須知道的八大數(shù)據(jù)結(jié)構(gòu)

前言

瑞士計算機(jī)科學(xué)家Niklaus Wirth在1976年寫了一本書杠园,名為《算法+數(shù)據(jù)結(jié)構(gòu)=編程》立肘。

40多年后,這個等式仍被奉為真理挺庞。這就是為什么在面試過程中,需要考察軟件工程師對數(shù)據(jù)結(jié)構(gòu)的理解稼病。

幾乎所有的問題都需要面試者對數(shù)據(jù)結(jié)構(gòu)有深刻的理解选侨。無論你是初入職場的新兵(剛從大學(xué)或者編程培訓(xùn)班畢業(yè)),還是擁有幾十年經(jīng)驗的職場老鳥然走。

有些面試題會明確提及某種數(shù)據(jù)結(jié)構(gòu)侵俗,例如,“給定一個二叉樹丰刊“ィ”而另一些則隱含在面試題中,例如,“我們希望記錄每個作者相關(guān)的書籍?dāng)?shù)量寻歧≌普ぃ”

即便是對于一些非常基礎(chǔ)的工作來說码泛,學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)也是必須的猾封。那么,就讓我們先從一些基本概念開始入手噪珊。

什么是數(shù)據(jù)結(jié)構(gòu)晌缘?

數(shù)據(jù)結(jié)構(gòu):計算機(jī)存儲、組織數(shù)據(jù)的方式痢站。數(shù)據(jù)結(jié)構(gòu)是指相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合蚂四。通常情況下齿穗,精心選擇的數(shù)據(jù)結(jié)構(gòu)可以帶來更高的運(yùn)行或者存儲效率跪妥。數(shù)據(jù)結(jié)構(gòu)往往同高效的檢索算法和索引技術(shù)有關(guān)漩蟆。

簡單地說,數(shù)據(jù)結(jié)構(gòu)是以某種特定的布局方式存儲數(shù)據(jù)的容器呜叫。這種“布局方式”決定了數(shù)據(jù)結(jié)構(gòu)對于某些操作是高效的空繁,而對于其他操作則是低效的。首先我們需要理解各種數(shù)據(jù)結(jié)構(gòu)朱庆,才能在處理實(shí)際問題時選取最合適的數(shù)據(jù)結(jié)構(gòu)盛泡。

為什么我們需要數(shù)據(jù)結(jié)構(gòu)?

數(shù)據(jù)是計算機(jī)科學(xué)當(dāng)中最關(guān)鍵的實(shí)體娱颊,而數(shù)據(jù)結(jié)構(gòu)則可以將數(shù)據(jù)以某種組織形式存儲饭于,因此,數(shù)據(jù)結(jié)構(gòu)的價值不言而喻维蒙。

無論你以何種方式解決何種問題掰吕,你都需要處理數(shù)據(jù)——無論是涉及員工薪水、股票價格颅痊、購物清單殖熟,還是只是簡單的電話簿問題。

數(shù)據(jù)需要根據(jù)不同的場景斑响,按照特定的格式進(jìn)行存儲菱属。有很多數(shù)據(jù)結(jié)構(gòu)能夠滿足以不同格式存儲數(shù)據(jù)的需求。

常見的數(shù)據(jù)結(jié)構(gòu)

首先列出一些最常見的數(shù)據(jù)結(jié)構(gòu)舰罚,我們將逐一說明:

  • 數(shù)組
  • 隊列
  • 鏈表
  • 字典樹(這是一種高效的樹形結(jié)構(gòu)纽门,但值得單獨(dú)說明)
  • 散列表(哈希表)

數(shù)組

所謂數(shù)組,是有序的元素序列营罢。若將有限個類型相同的變量的集合命名赏陵,那么這個名稱為數(shù)組名饼齿。組成數(shù)組的各個變量稱為數(shù)組的分量,也稱為數(shù)組的元素蝙搔,有時也稱為下標(biāo)變量缕溉。用于區(qū)分?jǐn)?shù)組的各個元素的數(shù)字編號稱為下標(biāo)。數(shù)組是在程序設(shè)計中吃型,為了處理方便证鸥, 把具有相同類型的若干元素按無序的形式組織起來的一種形式。這些無序排列的同類數(shù)據(jù)元素的集合稱為數(shù)組勤晚。

數(shù)組是用于儲存多個相同類型數(shù)據(jù)的集合枉层。

數(shù)組是最簡單、也是使用最廣泛的數(shù)據(jù)結(jié)構(gòu)赐写。棧鸟蜡、隊列等其他數(shù)據(jù)結(jié)構(gòu)均由數(shù)組演變而來。下圖是一個包含元素(1血淌,2矩欠,3和4)的簡單數(shù)組财剖,數(shù)組長度為4悠夯。


image.png

每個數(shù)據(jù)元素都關(guān)聯(lián)一個正數(shù)值,我們稱之為索引躺坟,它表明數(shù)組中每個元素所在的位置沦补。大部分語言將初始索引定義為零。

以下是數(shù)組的兩種類型:

  • 一維數(shù)組(如上所示)
  • 多維數(shù)組(數(shù)組的數(shù)組)

(1) 數(shù)組的基本操作

Insert——在指定索引位置插入一個元素
Get——返回指定索引位置的元素
Delete——刪除指定索引位置的元素
Size——得到數(shù)組所有元素的數(shù)量

(2) 面試中關(guān)于數(shù)組的常見問題

  • 尋找數(shù)組中第二小的元素
  • 找到數(shù)組中第一個不重復(fù)出現(xiàn)的整數(shù)
  • 合并兩個有序數(shù)組
  • 重新排列數(shù)組中的正值和負(fù)值

棧(stack)又名堆棧咪橙,它是一種運(yùn)算受限的線性表夕膀。限定僅在表尾進(jìn)行插入和刪除操作的線性表。這一端被稱為棧頂美侦,相對地产舞,把另一端稱為棧底.

可以把棧想象成一列垂直堆放的書。為了拿到中間的書菠剩,你需要移除放置在這上面的所有書易猫。這就是LIFO(后進(jìn)先出)的工作原理。

下圖是包含三個數(shù)據(jù)元素(1具壮,2和3)的棧准颓,其中頂部的3將被最先移除:


image.png

(1) 棧的基本操作

  • Push——在頂部插入一個元素
  • Pop——返回并移除棧頂元素
  • isEmpty——如果棧為空,則返回true
  • Top——返回頂部元素棺妓,但并不移除它

(2) 面試中關(guān)于棧的常見問題

  • 使用棧計算后綴表達(dá)式
  • 對棧的元素進(jìn)行排序
  • 判斷表達(dá)式是否括號平衡

隊列

隊列是一種特殊的線性表攘已,特殊之處在于它只允許在表的前端(front)進(jìn)行刪除操作,而在表的后端(rear)進(jìn)行插入操作怜跑,和棧一樣样勃,隊列是一種操作受限制的線性表。進(jìn)行插入操作的端稱為隊尾,進(jìn)行刪除操作的端稱為隊頭彤灶。

棧與隊列的最大差別在于棧是LIFO(后進(jìn)先出)看幼,而隊列是FIFO,即先進(jìn)先出幌陕。

一個完美的隊列現(xiàn)實(shí)例子:售票亭排隊隊伍诵姜。如果有新人加入,他需要到隊尾去排隊搏熄,而非隊首——排在前面的人會先拿到票棚唆,然后離開隊伍。

下圖是包含四個元素(1心例,2宵凌,3和4)的隊列,其中在頂部的1將被最先移除:

image.png

移除先入隊的元素止后、插入新元素

(1) 隊列的基本操作

  • Enqueue()?——?在隊列尾部插入元素
  • Dequeue()?——移除隊列頭部的元素
  • isEmpty()——如果隊列為空瞎惫,則返回true
  • Top()?——返回隊列的第一個元素

(2) 面試中關(guān)于隊列的常見問題

  • 使用隊列表示棧
  • 對隊列的前k個元素倒序
  • 使用隊列生成從1到n的二進(jìn)制數(shù)

鏈表

鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu)译株,數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的瓜喇。鏈表由一系列結(jié)點(diǎn)(鏈表中每一個元素稱為結(jié)點(diǎn))組成,結(jié)點(diǎn)可以在運(yùn)行時動態(tài)生成歉糜。每個結(jié)點(diǎn)包括兩個部分:一個是存儲數(shù)據(jù)元素的數(shù)據(jù)域乘寒,另一個是存儲下一個結(jié)點(diǎn)地址的指針域。

使用鏈表結(jié)構(gòu)可以克服數(shù)組鏈表需要預(yù)先知道數(shù)據(jù)大小的缺點(diǎn)匪补,鏈表結(jié)構(gòu)可以充分利用計算機(jī)內(nèi)存空間伞辛,實(shí)現(xiàn)靈活的內(nèi)存動態(tài)管理。但是鏈表失去了數(shù)組隨機(jī)讀取的優(yōu)點(diǎn)夯缺,同時鏈表由于增加了結(jié)點(diǎn)的指針域蚤氏,空間開銷比較大。鏈表最明顯的好處就是踊兜,常規(guī)數(shù)組排列關(guān)聯(lián)項目的方式可能不同于這些數(shù)據(jù)項目在記憶體磁盤上順序竿滨,數(shù)據(jù)的存取往往要在不同的排列順序中轉(zhuǎn)換。鏈表允許插入和移除表上任意位置上的節(jié)點(diǎn)润文,但是不允許隨機(jī)存取姐呐。

這是鏈表內(nèi)部結(jié)構(gòu)的展示:


image.png

(1) 鏈表包括以下類型:

  • 單鏈表(單向)
  • 雙向鏈表(雙向)

(2) 鏈表的基本操作:

  • InsertAtEnd - 在鏈表的末尾插入指定元素
  • InsertAtHead - 在鏈接列表的開頭/頭部插入指定元素
  • Delete? - 從鏈接列表中刪除指定元素
  • DeleteAtHead - 刪除鏈接列表的第一個元素
  • Search? - 從鏈表中返回指定元素
  • isEmpty - 如果鏈表為空,則返回true

圖是一組以網(wǎng)絡(luò)形式相互連接的節(jié)點(diǎn)典蝌。節(jié)點(diǎn)也稱為頂點(diǎn)(Vertex)曙砂。 一對節(jié)點(diǎn)(x,y)稱為邊(edge)骏掀,表示頂點(diǎn)x連接到頂點(diǎn)y鸠澈。邊可以包含權(quán)重/成本柱告,顯示從頂點(diǎn)x到y(tǒng)所需的成本。

圖是由頂點(diǎn)集合(Vertex)及頂點(diǎn)間的關(guān)系集合組成的一種數(shù)據(jù)結(jié)構(gòu):Graph=( V, E )
V = {x | x ∈某個數(shù)據(jù)對象 } 是頂點(diǎn)的有窮非空集合笑陈;
E ={ (x, y) | x, y ∈V } 是頂點(diǎn)之間關(guān)系的有窮集合际度,也叫做邊(Edge)集合。

image.png

(1) 圖的類型

  • 無向圖
  • 有向圖

(2) 在程序語言中涵妥,圖可以用兩種形式表示:

  • 鄰接矩陣
  • 鄰接表

(3) 常見圖遍歷算法

  • 廣度優(yōu)先搜索
  • 深度優(yōu)先搜索

(4) 面試中關(guān)于圖的常見問題

  • 實(shí)現(xiàn)廣度和深度優(yōu)先搜索
  • 檢查圖是否為樹
  • 計算圖的邊數(shù)
  • 找到兩個頂點(diǎn)之間的最短路徑

樹形結(jié)構(gòu)是一種層級式的數(shù)據(jù)結(jié)構(gòu)乖菱,由頂點(diǎn)(節(jié)點(diǎn))和連接它們的邊組成。 樹類似于圖蓬网,但區(qū)分樹和圖的重要特征是樹中不存在環(huán)路窒所。

樹形結(jié)構(gòu)被廣泛應(yīng)用于人工智能和復(fù)雜算法,它可以提供解決問題的有效存儲機(jī)制帆锋。

這是一個簡單樹的示意圖吵取,以及樹數(shù)據(jù)結(jié)構(gòu)中使用的基本術(shù)語:

image.png
  • Root - 根節(jié)點(diǎn)
  • Parent - 父節(jié)點(diǎn)
  • Child - 子節(jié)點(diǎn)
  • Leaf - 葉子節(jié)點(diǎn)
  • Sibling - 兄弟節(jié)點(diǎn)

(1) 以下是樹形結(jié)構(gòu)的主要類型:

  • N元樹
  • 平衡樹
  • 二叉樹
  • 二叉搜索樹
  • AVL樹
  • 紅黑樹
  • 2-3樹

其中,二叉樹和二叉搜索樹是最常用的樹

(2) 面試中關(guān)于樹結(jié)構(gòu)的常見問題:

  • 求二叉樹的高度
  • 在二叉搜索樹中查找第k個最大值
  • 查找與根節(jié)點(diǎn)距離k的節(jié)點(diǎn)
  • 在二叉樹中查找給定節(jié)點(diǎn)的祖先節(jié)點(diǎn)

字典樹(Trie)

又稱單詞查找樹锯厢,Trie樹皮官,是一種樹形結(jié)構(gòu),是一種哈希樹的變種实辑。典型應(yīng)用是用于統(tǒng)計捺氢,排序和保存大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計徙菠。它的優(yōu)點(diǎn)是:利用字符串的公共前綴來減少查詢時間讯沈,最大限度地減少無謂的字符串比較郁岩,查詢效率比哈希樹高婿奔。

以下是在字典樹中存儲三個單詞“top”,“thus”和“their”的例子:

image.png

這些單詞以頂部到底部的方式存儲问慎,其中綠色節(jié)點(diǎn)“p”萍摊,“s”和“r”分別表示“top”,“thus”和“theirs”的底部如叼。

哈希表

散列表(Hash table冰木,也叫哈希表),是根據(jù)關(guān)鍵碼值(Key value)而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)笼恰。也就是說踊沸,它通過把關(guān)鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度社证。這個映射函數(shù)叫做散列函數(shù)逼龟,存放記錄的數(shù)組叫做散列表

給定表M追葡,存在函數(shù)f(key)腺律,對任意給定的關(guān)鍵字值key奕短,代入函數(shù)后若能得到包含該關(guān)鍵字的記錄在表中的地址,則稱表M為哈希(Hash)表匀钧,函數(shù)f(key)為哈希(Hash) 函數(shù)翎碑。

哈希表通常使用數(shù)組實(shí)現(xiàn)。

散列數(shù)據(jù)結(jié)構(gòu)的性能取決于以下三個因素:

  • 哈希函數(shù)
  • 哈希表的大小
  • 碰撞處理方法

以上是在編程面試之前你應(yīng)該知曉的八大數(shù)據(jù)結(jié)構(gòu)之斯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末日杈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子佑刷,更是在濱河造成了極大的恐慌达椰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件项乒,死亡現(xiàn)場離奇詭異啰劲,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)檀何,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門蝇裤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人频鉴,你說我怎么就攤上這事栓辜。” “怎么了垛孔?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵藕甩,是天一觀的道長。 經(jīng)常有香客問我周荐,道長狭莱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任概作,我火速辦了婚禮腋妙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘讯榕。我一直安慰自己骤素,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布愚屁。 她就那樣靜靜地躺著济竹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪霎槐。 梳的紋絲不亂的頭發(fā)上送浊,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音栽燕,去河邊找鬼罕袋。 笑死改淑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浴讯。 我是一名探鬼主播朵夏,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼榆纽!你這毒婦竟也來了仰猖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤奈籽,失蹤者是張志新(化名)和其女友劉穎饥侵,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衣屏,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡躏升,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了狼忱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膨疏。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钻弄,靈堂內(nèi)的尸體忽然破棺而出佃却,到底是詐尸還是另有隱情,我是刑警寧澤窘俺,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布饲帅,位于F島的核電站,受9級特大地震影響瘤泪,放射性物質(zhì)發(fā)生泄漏灶泵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一均芽、第九天 我趴在偏房一處隱蔽的房頂上張望丘逸。 院中可真熱鬧单鹿,春花似錦掀宋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至儒喊,卻和暖如春镣奋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怀愧。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工侨颈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留余赢,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓哈垢,卻偏偏與公主長得像妻柒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耘分,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

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