轉(zhuǎn)載地址 https://blog.fundebug.com/2018/08/27/code-interview-data-structure/
譯者按:?搞定面試,不要急著刷題褪测,先弄懂什么是數(shù)據(jù)結(jié)構(gòu)恋拷!
原文:The top data structures you should know for your next coding interview
譯者:Fundebug
為了保證可讀性应结,本文采用意譯而非直譯兜辞。另外悉默,本文版權(quán)歸原作者所有哮缺,翻譯僅用于學(xué)習(xí)。
1976年妓忍,一個(gè)瑞士計(jì)算機(jī)科學(xué)家寫一本書《Algorithms + Data Structures = Programs》虏两。即:算法 + 數(shù)據(jù)結(jié)構(gòu) = 程序。40多年過去了世剖,這個(gè)等式依然成立定罢。
很多代碼面試題都要求候選者深入理解數(shù)據(jù)結(jié)構(gòu),不管你來自大學(xué)計(jì)算機(jī)專業(yè)還是編程培訓(xùn)機(jī)構(gòu)旁瘫,也不管你有多少年編程經(jīng)驗(yàn)祖凫。有時(shí)面試題會(huì)直接提到數(shù)據(jù)結(jié)構(gòu),比如“給我實(shí)現(xiàn)一個(gè)二叉樹”酬凳,然而有時(shí)則不那么明顯惠况,比如“統(tǒng)計(jì)一下每個(gè)作者寫的書的數(shù)量”。
數(shù)據(jù)結(jié)構(gòu)是計(jì)算機(jī)存儲(chǔ)稠屠、組織數(shù)據(jù)的方式。對(duì)于特定的數(shù)據(jù)結(jié)構(gòu)(比如數(shù)組),有些操作效率很高(讀某個(gè)數(shù)組元素)完箩,有些操作的效率很低(刪除某個(gè)數(shù)組元素)赐俗。程序員的目標(biāo)是為當(dāng)前的問題選擇最優(yōu)的數(shù)據(jù)結(jié)構(gòu)。
為什么我們需要數(shù)據(jù)結(jié)構(gòu)弊知?
數(shù)據(jù)是程序的核心要素阻逮,因此數(shù)據(jù)結(jié)構(gòu)的價(jià)值不言而喻。無論你在寫什么程序秩彤,你都需要與數(shù)據(jù)打交道叔扼,比如員工工資、股票價(jià)格漫雷、雜貨清單或者電話本瓜富。在不同場(chǎng)景下,數(shù)據(jù)需要以特定的方式存儲(chǔ)降盹,我們有不同的數(shù)據(jù)結(jié)構(gòu)可以滿足我們的需求与柑。
數(shù)組
棧
隊(duì)列
鏈表
圖
樹
前綴樹
哈希表
數(shù)組(Array)大概是最簡(jiǎn)單,也是最常用的數(shù)據(jù)結(jié)構(gòu)了蓄坏。其他數(shù)據(jù)結(jié)構(gòu)价捧,比如棧和隊(duì)列都是由數(shù)組衍生出來的。
下圖展示了1個(gè)數(shù)組涡戳,它有4個(gè)元素:
每一個(gè)數(shù)組元素的位置由數(shù)字編號(hào)结蟋,稱為下標(biāo)或者索引(index)。大多數(shù)編程語言的數(shù)組第一個(gè)元素的下標(biāo)是0渔彰。
根據(jù)維度區(qū)分嵌屎,有2種不同的數(shù)組:
一維數(shù)組(如上圖所示)
多維數(shù)組(數(shù)組的元素為數(shù)組)
Insert - 在某個(gè)索引處插入元素
Get - 讀取某個(gè)索引處的元素
Delete - 刪除某個(gè)索引處的元素
Size - 獲取數(shù)組的長(zhǎng)度
重新排列數(shù)組中的正數(shù)和負(fù)數(shù)
撤回,即Ctrl+Z恍涂,是我們最常見的操作之一宝惰,大多數(shù)應(yīng)用都會(huì)支持這個(gè)功能。你知道它是怎么實(shí)現(xiàn)的嗎再沧?答案是這樣的:把之前的應(yīng)用狀態(tài)(限制個(gè)數(shù))保存到內(nèi)存中掌测,最近的狀態(tài)放到第一個(gè)。這時(shí)产园,我們需要棧(stack)來實(shí)現(xiàn)這個(gè)功能。
棧中的元素采用LIFO (Last In First Out)夜郁,即后進(jìn)先出什燕。
下圖的棧有3個(gè)元素,3在最上面竞端,因此它會(huì)被第一個(gè)移除:
Push?—?在棧的最上方插入元素
Pop?— 返回棧最上方的元素屎即,并將其刪除
isEmpty?—?查詢棧是否為空
Top?—?返回棧最上方的元素,并不刪除
隊(duì)列(Queue)與棧類似,都是采用線性結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)技俐。它們的區(qū)別在于乘陪,棧采用LIFO方式,而隊(duì)列采用先進(jìn)先出雕擂,即FIFO(First in First Out)啡邑。
下圖展示了一個(gè)隊(duì)列,1是最上面的元素井赌,它會(huì)被第一個(gè)移除:
Enqueue?—?在隊(duì)列末尾插入元素
Dequeue?—?將隊(duì)列第一個(gè)元素刪除
isEmpty?—?查詢隊(duì)列是否為空
Top?—?返回隊(duì)列的第一個(gè)元素
使用隊(duì)列將1到n轉(zhuǎn)換為二進(jìn)制
鏈表(Linked List)也是線性結(jié)構(gòu)谤逼,它與數(shù)組看起來非常像,但是它們的內(nèi)存分配方式仇穗、內(nèi)部結(jié)構(gòu)和插入刪除操作方式都不一樣流部。
鏈表是一系列節(jié)點(diǎn)組成的鏈,每一個(gè)節(jié)點(diǎn)保存了數(shù)據(jù)以及指向下一個(gè)節(jié)點(diǎn)的指針纹坐。鏈表頭指針指向第一個(gè)節(jié)點(diǎn)枝冀,如果鏈表為空,則頭指針為空或者為null耘子。
鏈表可以用來實(shí)現(xiàn)文件系統(tǒng)果漾、哈希表和鄰接表。
下圖展示了一個(gè)鏈表拴还,它有3個(gè)節(jié)點(diǎn):
鏈表分為2種:
單向鏈表
雙向鏈表
InsertAtEnd?—?在鏈表結(jié)尾插入元素
InsertAtHead?—?在鏈表開頭插入元素
Delete?—?刪除鏈表的指定元素
DeleteAtHead?—?刪除鏈表第一個(gè)元素
Search?—?在鏈表中查詢指定元素
isEmpty?—?查詢鏈表是否為空
圖(graph)由多個(gè)節(jié)點(diǎn)(vertex)構(gòu)成跨晴,節(jié)點(diǎn)之間闊以互相連接組成一個(gè)網(wǎng)絡(luò)。(x, y)表示一條邊(edge)片林,它表示節(jié)點(diǎn)x與y相連端盆。邊可能會(huì)有權(quán)值(weight/cost)。
圖分為兩種:
無向圖
有向圖
在編程語言中费封,圖有可能有以下兩種形式表示:
鄰接矩陣(Adjacency Matrix)
鄰接表(Adjacency List)
遍歷圖有兩周算法
廣度優(yōu)先搜索(Breadth First Search)
深度優(yōu)先搜索(Depth First Search)
使用Dijkstra算法查找兩個(gè)節(jié)點(diǎn)之間的最短距離
樹(Tree)是一個(gè)分層的數(shù)據(jù)結(jié)構(gòu)焕妙,由節(jié)點(diǎn)和連接節(jié)點(diǎn)的邊組成。樹是一種特殊的圖弓摘,它與圖最大的區(qū)別是沒有循環(huán)焚鹊。
樹被廣泛應(yīng)用在人工智能和一些復(fù)雜算法中,用來提供高效的存儲(chǔ)結(jié)構(gòu)韧献。
下圖是一個(gè)簡(jiǎn)單的樹以及與樹相關(guān)的術(shù)語:
樹有很多分類:
N叉樹(N-ary Tree)
平衡樹(Balanced Tree)
二叉樹(Binary Tree)
二叉查找樹(Binary Search Tree)
平衡二叉樹(AVL Tree)
紅黑樹(Red Black Tree)
2-3樹(2–3 Tree)
其中末患,二叉樹和二叉查找樹是最常用的樹。
查找樹中與根節(jié)點(diǎn)距離為k的節(jié)點(diǎn)
查找二叉樹中某個(gè)節(jié)點(diǎn)所有祖先節(jié)點(diǎn)
前綴樹(Prefix Trees或者Trie)與樹類似锤窑,用于處理字符串相關(guān)的問題時(shí)非常高效璧针。它可以實(shí)現(xiàn)快速檢索,常用于字典中的單詞查詢渊啰,搜索引擎的自動(dòng)補(bǔ)全甚至IP路由探橱。
下圖展示了“top”, “thus”和“their”三個(gè)單詞在前綴樹中如何存儲(chǔ)的:
單詞是按照字母從上往下存儲(chǔ)申屹,“p”, “s”和“r”節(jié)點(diǎn)分別表示“top”, “thus”和“their”的單詞結(jié)尾。
統(tǒng)計(jì)前綴樹表示的單詞個(gè)數(shù)
哈希(Hash)將某個(gè)對(duì)象變換為唯一標(biāo)識(shí)符隧膏,該標(biāo)識(shí)符通常用一個(gè)短的隨機(jī)字母和數(shù)字組成的字符串來代表哗讥。哈希可以用來實(shí)現(xiàn)各種數(shù)據(jù)結(jié)構(gòu)胞枕,其中最常用的就是哈希表(hash table)杆煞。
哈希表通常由數(shù)組實(shí)現(xiàn)。
哈希表的性能取決于3個(gè)指標(biāo):
哈希函數(shù)
哈希表的大小
哈希沖突處理方式
下圖展示了有數(shù)組實(shí)現(xiàn)的哈希表曲稼,數(shù)組的下標(biāo)即為哈希值索绪,由哈希函數(shù)計(jì)算,作為哈希表的鍵(key)贫悄,而數(shù)組中保存的數(shù)據(jù)即為值(value):