數據結構與算法之美學習筆記:第四十八講

1、解決問題的前提是定義清楚問題

經過對一些模糊需求進行假設,來限定要解決問題的範圍

根據某個值查找數據,好比 select * from use where id=1234;
根據區間值來查詢某些數據好比 select * from use where id > 1234 and id < 2345java

性能方面的需求,咱們主要考察時間和空間兩方面,也就是執行效率和存儲空間

執行效率:我麼你但願經過索引,查詢數據的效率儘量的高;
存儲空間方面咱們但願索引不須要消耗太多的內存空間數據庫

2、嘗試用學過的數據結構解決這個問題

支持快速查詢、插入等操做的動態數據結構,咱們已經學過散列表、平衡二叉樹、跳錶
數據結構

這樣看來,跳錶是能夠解決這個問題,實際上,數據庫索引所用到的數據結構跟跳錶很是類似,叫作B+樹
它是經過跳錶演化僱來的,而非跳錶性能

3、改造二叉查找樹來解決這個問題

一、實現代碼

/**
 * 這是 B+ 樹非葉子節點的定義。
 *
 * 假設 keywords=[3, 5, 8, 10]
 * 4 個鍵值將數據分爲 5 個區間:(-INF,3), [3,5), [5,8), [8,10), [10,INF)
 * 5 個區間分別對應:children[0]...children[4]
 *
 * m 值是事先計算獲得的,計算的依據是讓全部信息的大小正好等於頁的大小:
 * PAGE_SIZE = (m-1)*4[keywordss 大小]+m*8[children 大小]
 */
public class BPlusTreeNode {
  public static int m = 5; // 5 叉樹
  public int[] keywords = new int[m-1]; // 鍵值,用來劃分數據區間
  public BPlusTreeNode[] children = new BPlusTreeNode[m];// 保存子節點指針
}

/**
 * 這是 B+ 樹中葉子節點的定義。
 *
 * B+ 樹中的葉子節點跟內部結點是不同的,
 * 葉子節點存儲的是值,而非區間。
 * 這個定義裏,每一個葉子節點存儲 3 個數據行的鍵值及地址信息。
 *
 * k 值是事先計算獲得的,計算的依據是讓全部信息的大小正好等於頁的大小:
 * PAGE_SIZE = k*4[keyw.. 大小]+k*8[dataAd.. 大小]+8[prev 大小]+8[next 大小]
 */
public class BPlusTreeLeafNode {
  public static int k = 3;
  public int[] keywords = new int[k]; // 數據的鍵值
  public long[] dataAddress = new long[k]; // 數據地址

  public BPlusTreeLeafNode prev; // 這個結點在鏈表中的前驅結點
  public BPlusTreeLeafNode next; // 這個結點在鏈表中的後繼結點
}

二、實現步驟

三、實現思路

分裂合併spa

四、刪除操做的例子

4、總結引伸

一、每一個節點中子節點的個數不能超過m,也不能小於m/2
二、根節點的子節點個數不可超過m/2,這是一個例外
三、M叉樹只存儲索引,並不真正存儲數據,這個有點相似跳錶
四、經過鏈表將葉子階段串聯在一次,這樣能夠方便區間查詢
五、通常狀況下,根節點會被存儲在內存中,其餘節點存儲在磁盤中3d

相關文章
相關標籤/搜索