2018年面試大資料面試資料結構總結
目錄
在面試大資料工作的過程中。中大型公司,都會對資料結構和演算法方面的知識有一定的要求。
由於是從Java開發轉的大資料,那麼在學習資料結構,也是與Java語言相關的資料結構學習為主,總結一下資料結構的知識。
資料結構的定義
百度的定義:資料結構是計算機儲存、組織資料的方式。資料結構是指相互之間存在一種或多種特定關係的資料元素的集合。通常情況下,精心選擇的資料結構可以帶來更高的執行或者儲存效率。
自己理解:資料結構就是定義資料的邏輯結構和物理儲存結構,並且分析兩者之間的聯絡。
資料結構的分類
邏輯結構分類
即平時以程式碼開發的形式操作的資料結構,可以分為2類8種。
邏輯結構一般分為2大類:線性結構和非線性結構。線性結構中有且僅有一個開始結點和一個終端結點,並且所有的結點最多隻能有一個前驅和一個後繼。線性表是典型的線性結構。非線性結構的一個結點可能有多個前驅和後繼。如果一個結點最多隻有一個前驅,而可以有多個後繼,這種結構就是樹。樹是最重要的非線性結構之一。如果對結點的前驅和後繼的個數不做限制,這種結構就是圖。圖是最一般的非線性結構。
資料結構一般分為以下8種:
- 陣列
- 連結串列
- 棧
- 佇列
- 堆
- 散列表
- 樹型結構
- 圖狀結構
在面試中常常問到的是樹形結構。
物理結構分類
物理結構即資料的儲存結構,描述的是資料具體在記憶體中的儲存。
- 順序結構
- 鏈式結構
- 雜湊結構
- 索引結構
相關概念
時間複雜度
這個概念可以在後期補充,主要是體現資料結構或者演算法的高效性。
如果學過高等數學,可以類比為程式執行次數的高階無窮小/同階無窮小函式。
hash
被翻譯成“雜湊”,也可以直譯成雜湊。就是把任意長度的輸入,通過hash函式,變成固定長度的輸出。該輸出值就是雜湊值。
表示式:value=hash(key)。
在Java中的應用:即每個物件的hashCode()方法。
詳細分析的連結:https://www.cnblogs.com/dolphin0520/p/3681042.html
hash衝突
以Java中的HashMap舉例。即以key經過hash函式計算後得到的地址去存入value的時候,發現此地址已經存在了value值。此時即產生了hash衝突。
解決辦法:
- 開放地址法
- 再hash法
- 鏈地址法
重點了解鏈地址法,在JDK1.7中HashMap解決hash衝突的方式就是鏈地址法。面試中不需要了解解決辦法,若想了解可自行百度。
Java中的陣列結構
Java中宣告一個數組就是在記憶體空間中開闢出一段連續的空間。
- 陣列的名字代表連續空間的首地址
- 通過陣列的名字可以依次訪問陣列中的每個元素
- 元素在陣列中的排序叫做下標且依次遞增
陣列的特性
- 陣列的長度一旦宣告,不可改變
- 陣列中僅能存同一型別的元素
陣列可以看做是一種特殊的線性表。特殊之處在於:陣列的元素也是以一種線性表。根據下標讀/寫任何元素的時間複雜度都為o(1)
但是二維陣列、廣義表、樹、圖等都是非線性結構。
線性表
線性表是一種典型的線性結構,頭結點無前驅,尾結點無後驅。
面試時僅需瞭解基本的線性表:陣列、單項鍊表、雙向連結串列。
在Java中,若是實現了AbstractList的集合類,都可認為是線性表結構,例如ArrayList、Vector、LinkedList。
注:List中的元素是有序排列且可重複,故稱之為序列。
ArrayList
ArrayList的底層實現仍然是陣列。ArrayList在建立的時候,會預設建立一個長度固定的陣列,對於數量小於這個長度的資料來說,在存入的過程中,可以說ArrayList是動態的。當資料的原始陣列容量,會將原來元素拷貝到一個容量更大的陣列中。
ArrayList的缺點
- ArrayList的效率相對於陣列來說更低
- ArrayList不能儲存基本資料型別(各種基本資料型別需要轉換成對應的包裝類)
ArrayList的原始碼分析:https://www.cnblogs.com/skywang12345/p/3308556.html
LinkedList
連結串列
一般僅需要知道單向連結串列即可。
連結串列的特點:增刪快,查詢慢。
連結串列資料結構學習連結:http://www.cnblogs.com/skywang12345/p/3561803.html
Java中的實現
https://www.cnblogs.com/skywang12345/p/3308556.html
Vector
由於ArrayList不是執行緒安全的,故僅能在單執行緒時使用。在多執行緒時使用Vector或者CopyOnWriteArrayList。
棧和佇列
棧(stack)是一種線性儲存結構,有以下特點:
- 棧中資料只能按照後進先出的方式進出棧;
- 向棧中新增/刪除元素時,只能從頂部開始操作。
棧在Java中的應用
在JVM中的棧區,就是使用的這種理念。故在每次程式的方法進行遞迴的時候,都會呼叫一次方法進行壓棧。當遞迴的方法找到出口的時候,即是最後一次呼叫遞迴方法。執行棧中的方法時,遵循的便是後進先出。
JDK1.7中HashMap的實現
雜湊表
百度百科:散列表(Hash table,也叫雜湊表),是根據關鍵碼值(Key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式(雜湊函式),存放記錄的陣列叫做散列表。
給定表M,存在函式f(key),對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的地址,則稱表M為雜湊(Hash)表,函式f(key)為雜湊(Hash) 函式。
Hashtable
Hashtable由於為了執行緒安全,在每個方法都加了鎖。而在平時開發中多是在單執行緒情況下操作,故在JDK1.2中HashMap出現後,逐漸被被淘汰,如今已經過時。
HashMap
HashMap維護了一張雜湊表,用來解決雜湊衝突問題。在JDK1.8之前,HashMap主要是由陣列+連結串列的方式實現的。而連結串列主要的目的就是為了解決Hash衝突問題。雜湊表即雜湊陣列,陣列中的每個元素即單鏈表的頭結點。如果不同資料對映到了陣列的同一個位置,就存放在Entry連結串列中。
HashMap的底層原始碼及細節分析:https://blog.csdn.net/ns_code/article/details/36034955
HashMap與Hashtable的對比分析:https://blog.csdn.net/fujiakai/article/details/51585767
樹
樹的基本概念網上一搜便可學習,這裡我附上一個連線:https://blog.csdn.net/DouBoomFly/article/details/70171410
掌握以下基本概念:
- 結點
- 葉子
- 度
- 層次
- 二叉樹
- 有序樹
- 平衡樹
平衡二叉樹的建立及遍歷
二叉樹的先序遍歷:根結點->左結點->後結點
二叉樹的中序遍歷:左結點->根結點->後結點
二叉樹的後序遍歷:左結點->右結點->根結點
//二叉樹結點
public class BSTree{
private int val;
private BSTree left;
private BsTree right;
BSTree(int data){
val=data;
left=null;
right=null;
}
}
public class BSTreeBuilder{
/*給二叉樹中新增值
*root:結點
*data:待插入的值
**/
public static insert(BSTree root,int data){
if(root.val>data){
if(root.left==null)
root.left=new BSTree(data);
else
insert(root,data);
}else{
if(root.right==null)
root.right=new BSTree(data);
else
insert(root,data);
}
}
//先序遍歷二叉樹
public static binSearch(BSTree root){
if(root!=null){
System.out.println("root.value: "+root.val);
binSearch(root.left);
binSearch(root.right);
}
}
//中序遍歷二叉樹
public static binSearch(BSTree root){
if(root!=null){
binSearch(root.left);
System.out.println("root.value: "+root.val);
binSearch(root.right);
}
}
//後序遍歷二叉樹
public static binSearch(BSTree root){
if(root!=null){
binSearch(root.left);
binSearch(root.right);
System.out.println("root.value: "+root.val);
}
}
}
注:在Java中的多數遍歷方式的實現,都是採用中序遍歷的方式,故主要記住中序遍歷。
紅黑樹
紅黑樹的概念比較複雜,由於在JDK1.8之後,HashMap採用紅黑樹來取代了原來的連結串列結構,以解決連結串列儲存資料導致的死迴圈問題,所以紅黑樹還是有學習的必要的。但是僅僅從順序二叉樹、平衡二叉樹的角度去掌握紅黑樹就行。至於它的時間複雜度等,都可以暫時不去考慮。
紅黑樹的特性:
(1)每個節點或者是黑色,或者是紅色。
(2)根節點是黑色。
(3)每個葉子節點(NIL)是黑色。 [注意:這裡葉子節點,是指為空(NIL或NULL)的葉子節點!]
(4)如果一個節點是紅色的,則它的子節點必須是黑色的。
(5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。
注意:
(01) 特性(3)中的葉子節點,是隻為空(NIL或null)的節點。
(02) 特性(5),確保沒有一條路徑會比其他路徑長出倆倍。因而,紅黑樹是相對是接近平衡的二叉樹。
紅黑樹的深入學習的連結:https://www.cnblogs.com/CarpenterLee/p/5503882.html
JDK1.8中的HashMap