10 道資料結構演算法題,不看答案你會幾道題
文章首將對應問題羅列,可以根據目錄找到感興趣的
- ArrayList 和 LinkedList 區別?結合資料結構說明
- B Tree 和 B+ Tree 區別?兩個 Tree 對比各自優勢
- Mysql 資料庫為什麼要使用樹結構充當索引結構
- LinkedList 的插入時間複雜度
- 氣泡排序的 3 種方式?哪種效能最好
- 氣泡排序的平均時間複雜度以及空間複雜度分別是多少
- 平衡二叉樹和紅黑樹的區別
- HashMap 中的 key 可以儲存可變引用型別麼?有什麼壞處?有什麼解決方案
- 什麼是Trie樹(字典樹)
- 為什麼 hashMap 的大小是 2 的 n 次方?(結合二進位制)
ArrayList 和 LinkedList 區別?結合資料結構說明
ArrayList 底層是使用動態陣列儲存的資料結構,如果查詢採用的定位方式是索引下標定位(還有根據元素定位 O(n)),時間複雜度為 O(1),所以查詢效率會很快,但是增、刪效率不好,如果是向尾部新增元素效率高
因為 ArrayList 類採用的儲存結構是連續的記憶體儲存,如果進行刪改元素將會對涉及到的陣列原有元素進行重排,所以特點是查詢快,增刪慢;並且在長度大於初始長度的話,會對陣列進行擴容
LinkedList 底層是使用雙向連結串列的形式進行儲存,查詢時間複雜度是 O(n),所以查詢會比較慢,但是增刪會很快,因為不涉及到對現有元素的重排
如果是增加元素的話,則對所增加元素的前序節點和後序節點改為插入位置的前後元素,將前後元素的前序節點和後序節點改為所增加的元素即可
B-Tree 和 B+ Tree 區別?兩個 Tree 對比各自優勢
B-tree 演算法減少定位記錄時所經歷的中間過程,從而加快存取速度。普遍運用在資料庫和檔案系統
B-Tree:
-
跟節點至少有兩個節點
-
首先從根節點進行二分查詢,如果找到則返回對應節點的 data,否則對相應區間的指標指向的節點遞迴進行查詢,直到找到節點或找到 null 指標,前者查詢成功,後者查詢失敗
B+Tree:
-
有 k 個子結點的結點必然有 k 個關鍵碼
-
非葉結點僅具有索引作用,跟記錄有關的資訊均存放在葉結點中
-
樹的所有葉結點構成一個有序連結串列,可以按照關鍵碼排序的次序遍歷全部記錄
這個優化的目的是為了提高區間訪問的效能
B-Tree 優點:
由於 B-Tree 的每一個節點都包含 key 和 value,因此經常訪問的元素可能離根節點更近,因此訪問也更迅速
B+Tree 優點:
-
B+Tree 的非葉子結點只包含導航資訊,不包含實際的值,所有的葉子結點和相連的節點使用連結串列相連,便於區間查詢和遍歷
-
由於 B+Tree 在內部節點上不包含資料資訊,因此在記憶體頁中能夠存放更多的 key。 資料存放的更加緊密,具有更好的空間區域性性。因此訪問葉子節點上關聯的資料也具有更好的快取命中率
-
B+Tree 的葉子結點都是相鏈的,因此對整棵樹的便利只需要一次線性遍歷葉子結點即可。而且由於資料順序排列並且相連,所以便於區間查詢和搜尋。而 B 樹則需要進行每一層的遞迴遍歷。相鄰的元素可能在記憶體中不相鄰,所以快取命中性沒有 B+Tree 好
Mysql 資料庫為什麼要使用樹結構充當索引結構
索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存的磁碟上
這樣的話,索引查詢過程中就要產生磁碟 I/O 消耗,相對於記憶體存取,I/O 存取的消耗要高几個數量級,所以評價一個資料結構作為索引的優劣最重要的指標就是在查詢過程中磁碟 I/O 操作次數的漸進複雜度。換句話說,索引的結構組織要儘量減少查詢過程中磁碟 I/O 的存取次數
LinkedList 的插入時間複雜度
如果執行 add(E e) 時間複雜度為 O(1),只需要獲取 last 元素,修改節點引用即可,如果使用 add(int index, E element)時間複雜度為 O(n),假如插入位置為 5,需要先查詢到第 5 個節點,然後只需要修改前後引用即可,不用進行元素移動
與 Arraylist 的最大特點,而是記憶體空間上的節省,因為 ArrayList 進行增刪元素時,會造成陣列元素重排,會將元素移動到新的陣列
氣泡排序的 3 種方式?
什麼是氣泡排序
-
將一個數與它後面的那一個數進行比較,如果前面>後面,則兩者交換位置
-
對陣列中的每一個數都進行這樣的操作,一個迴圈下來最大的數值就會到達陣列的最後面
-
再將陣列範圍縮小一個(即再次比較時不看陣列最後且最大的那個),再次迴圈上面的步驟
-
當陣列的範圍縮小到只剩下一個數的時候,那麼陣列就已經有序了,氣泡排序結束
最常見第一版氣泡排序
public static void sortFunc1(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
for (int i = arr.length - 1; i > 0; i--) {
for (int j = 0; j < arr.length - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j + 1, j);
}
}
}
}
第二版氣泡排序
public static void sortFunc2(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
boolean flag = true;
while (flag) {
flag = false;
for (int i = arr.length - 1; i > 0; i--) {
for (int j = 0; j < arr.length - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j + 1, j);
flag = true;
}
}
}
}
}
第三版氣泡排序
public static void sortFunc2(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
int flag = arr.length - 1;
while (flag > 0) {
int end = flag;
flag = 0;
for (int j = 0; j < end; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j + 1, j);
flag = j;
}
}
}
}
swap 交換演算法
public static void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
氣泡排序的平均時間複雜度以及空間複雜度分別是多少
平均時間複雜度:O(n2)
空間複雜度:O(1)
平衡二叉樹和紅黑樹的區別
- 紅黑樹放棄了追求完全平衡,追求大致平衡,在與平衡二叉樹的時間複雜度相差不大的情況下,保證每次插入最多隻需要三次旋轉就能達到平衡,實現起來也更為簡單
- 平衡二叉樹追求絕對平衡,條件比較苛刻,實現起來比較麻煩,每次插入新節點之後需要旋轉的次數不能預知
HashMap 中的 key 可以儲存可變引用型別麼?有什麼壞處?有什麼解決方案
可以定義為可變引用型別
假定一個 Student 物件為一個 hashMap 的 key,如果存入後,對物件進行了 set 操作,導致 hashCode 值改變,如果在使用 hashMap 的 get 操作查詢時,是查詢不到的
這種方式可以將 Student 物件的 hashCode 和 equals 方法來進行避免
什麼是Trie樹(字典樹)
trie,又稱字首樹,是一種有序樹,用於儲存關聯陣列,其中的鍵通常是字串。與二叉查詢樹不同,鍵不是直接儲存在節點中,而是由節點在樹中的位置決定。一個節點的所有子孫都有相同的字首,也就是這個節點對應的字串,而根節點對應空字串。一般情況下,不是所有的節點都有對應的值,只有葉子節點和部分內部節點所對應的鍵才有相關的值
在圖示中,鍵標註在節點中,值標註在節點之下。每一個完整的英文單詞對應一個特定的整數。Trie 可以看作是一個確定有限狀態自動機,儘管邊上的符號一般是隱含在分支的順序中的
鍵不需要被顯式地儲存在節點中。圖示中標註出完整的單詞,只是為了演示 trie 的原理
優點:利用字串的公共字首來節約儲存空間,最大限度地減少無謂的字串比較,查詢效率比雜湊表高
缺點:Trie樹是一種比較簡單的資料結構.理解起來比較簡單,正所謂簡單的東西也得付出代價.故Trie樹也有它的缺點,Trie樹的記憶體消耗非常大
為什麼 hashMap 的大小是 2 的 n 次方?(結合二進位制)
HashMap是根據key的hash值決定key放到哪個桶中,通過tab[i = (n - 1) & hash]公式計算得出
這裡的n是HashMap的容量,因為n永遠是2的次冪,所以n - 1通過二進位制表示,永遠都是末尾連續1的形式表示(如00001111、00000011),當(n - 1) 和hash做與運算時,會保留hash中後x位的1
例如00001111 & 10000011 = 00000011
這樣做的好處在於:
- &運算速度快,至少比%取模運算快
- 能保證索引值肯定在HashMap的容量大小範圍內
- (n - 1) & hash的值是均勻分佈的,可以減少hash衝突
結言
由於作者水平有限, 歡迎大家能夠反饋指正文章中錯誤不正確的地方, 感謝 ?
小夥伴的喜歡就是對我最大的支援, 如果讀了文章有所收穫, 希望能夠 點贊、評論、關注三連!
推薦閱讀:
- 【強烈推薦】1w 字,18 張圖,徹底說清 springboot starter
- 【強烈推薦】謹慎使用 JDK 8 新特性並行流 ParallelStream
- 【強烈推薦】一文快速掌握 Redisson 如何實現分散式鎖原理
- 【大廠面試真題】JDK 執行緒池中如何不超最大執行緒數快速消費任務
- 【大廠面試真題】JDK 執行緒池如何保證核心執行緒不被銷燬
作者麻花,座標帝都 Java 後端研發,勵志成為架構師的一枚處女座程式設計師,專注高併發、框架底層原始碼、分散式等知識分享
相關文章
- 資料結構與演算法面試題80道資料結構演算法面試題
- 27道Redis精選面試題,你會做幾題?Redis面試題
- 十幾道含答案的大廠面試題總結面試題
- 面試現場簡單幾道java演算法題, 你能寫出幾道?面試Java演算法
- 10道網路安全基礎面試題,你答對了幾道?面試題
- 這道js題你會嗎?JS
- 你能答對幾道SQL題?SQL
- 答案公佈 | AI衝頂大會你答對了幾道?AI
- 這10道javascript筆試題你都會麼JavaScript筆試
- 100道JAVA面試題+JAVA面試題參考答案Java面試題
- 面試中常見的幾道智力題 來看看你會做幾道(2)?面試
- 10道Linux常見面試題,你知道幾個?Linux面試題
- 每日一道演算法題之陣列實現資料結構演算法陣列資料結構
- 一道看完答案你會覺得很沙雕的「動態規劃演算法題」動態規劃演算法
- 22道js輸出順序問題,你能做出幾道JS
- 30 道 Dubbo 面試題及答案面試題
- 技術面試中常見的幾道智力題 來看看你會做幾道?面試
- 10道Python基礎面試題附答案,你都掌握了嗎?Python面試題
- 【Java】幾道讓你拿offer的面試題Java面試題
- 75 道 BAJT 高階 Java 面試題,你能答上幾道?Java面試題
- 75 道 BAJT 中高階 Java 面試題,你能答上幾道?Java面試題
- 資料結構與演算法之一道題感受演算法(演算法入門)資料結構演算法
- Python最常見的10道面試題及答案Python面試題
- 幾道Java筆試題Java筆試
- 微軟等資料結構+演算法面試100題全部答案集錦微軟資料結構演算法面試
- 技術面試題分享:含答案的10道Jvm面試專題面試題JVM
- 幾道特別難搞的資料庫面試題資料庫面試題
- 微軟的100道演算法面試題(終結版)微軟演算法面試題
- 如果這10道關於資料庫的測試題你都會,面試必過!資料庫面試
- 這些javascript面試題,你做對了幾道?JavaScript面試題
- 【整理】最常見的10道Python面試題及答案!Python面試題
- 不懂Spring別說你會Java,Spring系列最全 66 道 面試題(含答案)SpringJava面試題
- 劍指offer中幾道演算法題的思考演算法
- C語言——幾道習題C語言
- 50道CSS基礎面試題(附答案)CSS面試題
- 50道 CSS 基礎面試題(附答案CSS面試題
- MySQL精選60道面試題 ( 含答案 )MySql面試題
- 吐血總結!50道Python面試題集錦(附答案)Python面試題