譯者按: 搞定面試,不要急著刷題,先弄懂什麼是數據結構! 原文 : "The top data structures you should know for your next coding interview" 譯者 : "Fundebug" 為了保證可讀性,本文采用意譯而非直譯。另外,本文版權歸 ...
譯者按: 搞定面試,不要急著刷題,先弄懂什麼是數據結構!
為了保證可讀性,本文采用意譯而非直譯。另外,本文版權歸原作者所有,翻譯僅用於學習。
1976年,一個瑞士電腦科學家寫一本書《Algorithms + Data Structures = Programs》。即:演算法 + 數據結構 = 程式。40多年過去了,這個等式依然成立。
很多代碼面試題都要求候選者深入理解數據結構,不管你來自大學電腦專業還是編程培訓機構,也不管你有多少年編程經驗。有時面試題會直接提到數據結構,比如“給我實現一個二叉樹”,然而有時則不那麼明顯,比如“統計一下每個作者寫的書的數量”。
什麼是數據結構?
數據結構是電腦存儲、組織數據的方式。對於特定的數據結構(比如數組),有些操作效率很高(讀某個數組元素),有些操作的效率很低(刪除某個數組元素)。程式員的目標是為當前的問題選擇最優的數據結構。
為什麼我們需要數據結構?
數據是程式的核心要素,因此數據結構的價值不言而喻。無論你在寫什麼程式,你都需要與數據打交道,比如員工工資、股票價格、雜貨清單或者電話本。在不同場景下,數據需要以特定的方式存儲,我們有不同的數據結構可以滿足我們的需求。
8種常用數據結構
- 數組
- 棧
- 隊列
- 鏈表
- 圖
- 樹
- 首碼樹
- 哈希表
1. 數組
數組(Array)大概是最簡單,也是最常用的數據結構了。其他數據結構,比如棧和隊列都是由數組衍生出來的。
下圖展示了1個數組,它有4個元素:
每一個數組元素的位置由數字編號,稱為下標或者索引(index)。大多數編程語言的數組第一個元素的下標是0。
根據維度區分,有2種不同的數組:
- 一維數組(如上圖所示)
- 多維數組(數組的元素為數組)
數組的基本操作
- Insert - 在某個索引處插入元素
- Get - 讀取某個索引處的元素
- Delete - 刪除某個索引處的元素
- Size - 獲取數組的長度
常見數組代碼面試題
2. 棧
撤回,即Ctrl+Z,是我們最常見的操作之一,大多數應用都會支持這個功能。你知道它是怎麼實現的嗎?答案是這樣的:把之前的應用狀態(限制個數)保存到記憶體中,最近的狀態放到第一個。這時,我們需要棧(stack)來實現這個功能。
棧中的元素採用LIFO (Last In First Out),即後進先出。
下圖的棧有3個元素,3在最上面,因此它會被第一個移除:
棧的基本操作
- Push — 在棧的最上方插入元素
- Pop — 返回棧最上方的元素,並將其刪除
- isEmpty — 查詢棧是否為空
- Top — 返回棧最上方的元素,並不刪除
常見的棧代碼面試題
3. 隊列
隊列(Queue)與棧類似,都是採用線性結構存儲數據。它們的區別在於,棧採用LIFO方式,而隊列採用先進先出,即FIFO(First in First Out)。
下圖展示了一個隊列,1是最上面的元素,它會被第一個移除:
隊列的基本操作
- Enqueue — 在隊列末尾插入元素
- Dequeue — 將隊列第一個元素刪除
- isEmpty — 查詢隊列是否為空
- Top — 返回隊列的第一個元素
常見的隊列代碼面試題
4. 鏈表
鏈表(Linked List)也是線性結構,它與數組看起來非常像,但是它們的記憶體分配方式、內部結構和插入刪除操作方式都不一樣。
鏈表是一系列節點組成的鏈,每一個節點保存了數據以及指向下一個節點的指針。鏈表頭指針指向第一個節點,如果鏈表為空,則頭指針為空或者為null。
鏈表可以用來實現文件系統、哈希表和鄰接表。
下圖展示了一個鏈表,它有3個節點:
鏈表分為2種:
- 單向鏈表
- 雙向鏈表
鏈表的基本操作
- InsertAtEnd — 在鏈表結尾插入元素
- InsertAtHead — 在鏈表開頭插入元素
- Delete — 刪除鏈表的指定元素
- DeleteAtHead — 刪除鏈表第一個元素
- Search — 在鏈表中查詢指定元素
- isEmpty — 查詢鏈表是否為空
常見的隊列代碼面試題
5. 圖
圖(graph)由多個節點(vertex)構成,節點之間闊以互相連接組成一個網路。(x, y)表示一條邊(edge),它表示節點x與y相連。邊可能會有權值(weight/cost)。
圖分為兩種:
- 無向圖
- 有向圖
在編程語言中,圖有可能有以下兩種形式表示:
- 鄰接矩陣(Adjacency Matrix)
- 鄰接表(Adjacency List)
遍歷圖有兩周演算法
- 廣度優先搜索(Breadth First Search)
- 深度優先搜索(Depth First Search)
常見的圖代碼面試題
6. 樹
樹(Tree)是一個分層的數據結構,由節點和連接節點的邊組成。樹是一種特殊的圖,它與圖最大的區別是沒有迴圈。
樹被廣泛應用在人工智慧和一些複雜演算法中,用來提供高效的存儲結構。
下圖是一個簡單的樹以及與樹相關的術語:
樹有很多分類:
- N叉樹(N-ary Tree)
- 平衡樹(Balanced Tree)
- 二叉樹(Binary Tree)
- 二叉查找樹(Binary Search Tree)
- 平衡二叉樹(AVL Tree)
- 紅黑樹(Red Black Tree)
- 2-3樹(2–3 Tree)
其中,二叉樹和二叉查找樹是最常用的樹。
常見的樹代碼面試題
7. 首碼樹
首碼樹(Prefix Trees或者Trie)與樹類似,用於處理字元串相關的問題時非常高效。它可以實現快速檢索,常用於字典中的單詞查詢,搜索引擎的自動補全甚至IP路由。
下圖展示了“top”, “thus”和“their”三個單詞在首碼樹中如何存儲的:
單詞是按照字母從上往下存儲,“p”, “s”和“r”節點分別表示“top”, “thus”和“their”的單詞結尾。
常見的樹代碼面試題
8. 哈希表
哈希(Hash)將某個對象變換為唯一標識符,該標識符通常用一個短的隨機字母和數字組成的字元串來代表。哈希可以用來實現各種數據結構,其中最常用的就是哈希表(hash table)。
哈希表通常由數組實現。
哈希表的性能取決於3個指標:
- 哈希函數
- 哈希表的大小
- 哈希衝突處理方式
下圖展示了有數組實現的哈希表,數組的下標即為哈希值,由哈希函數計算,作為哈希表的鍵(key),而數組中保存的數據即為值(value):
常見的哈希表代碼面試題
參考
- Fundebug博客 - Node.js面試題之2017
- Fundebug博客 - 快速掌握JavaScript面試基礎知識(一)
- Fundebug博客 - 快速掌握JavaScript面試基礎知識(二)
- Fundebug博客 - 快速掌握JavaScript面試基礎知識(三)
- GeeksforGeeks
關於Fundebug
Fundebug專註於JavaScript、微信小程式、微信小游戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了6億+錯誤事件,得到了Google、360、金山軟體等眾多知名用戶的認可。歡迎免費試用!
版權聲明:
轉載時請註明作者Fundebug以及本文地址:
https://blog.fundebug.com/2018/08/27/code-interview-data-structure/