本文轉自:http://blog.csdn.net/yang_yulei/article/details/46371975html
基數樹數組
對於長整型數據的映射,如何解決Hash衝突和Hash表大小的設計是一個很頭疼的問題。
radix樹就是針對這種稀疏的長整型數據查找,能快速且節省空間地完成映射。藉助於Radix樹,咱們能夠實現對於長整型數據類型的路由。
利用radix樹能夠根據一個長整型(好比一個長ID)快速查找到其對應的對象指針。這比用hash映射來的簡單,也更節省空間,使用hash映射hash函數難以設計,不恰當的hash函數可能增大沖突,或浪費空間。
radix tree是一種多叉搜索樹,樹的葉子結點是實際的數據條目。每一個結點有一個固定的、2^n指針指向子結點(每一個指針稱爲槽slot,n爲劃分的基的大小)
插入、刪除 緩存
radix Tree(基數樹) 其實就差很少是傳統的二叉樹,只是在尋找方式上,利用好比一個unsigned int的類型的每個比特位做爲樹節點的判斷。
能夠這樣說,好比一個數1000101010101010010101010010101010,那麼按照Radix 樹的插入就是在根節點,若是遇到0,就指向左節點,若是遇到1就指向右節點,在插入過程當中構造樹節點,在刪除過程當中刪除樹節點。若是以爲太多的調用Malloc的話,能夠採用池化技術,預先分配多個節點。
(使用一個比特位判斷,會使樹的高度太高,非葉節點過多。故在實際應用中,咱們通常是使用多個比特位做爲樹節點的判斷,但多比特位會使節點的子節點槽變多,增大節點的體積,通常選用2個或4個比特位做爲樹節點便可)
如圖:

插入:函數
咱們在插入一個新節點時,咱們根據數據的比特位,在樹中向下查找,若沒有相應結點,則生成相應結點,直到數據的比特位訪問完,則創建葉節點映射相應的對象。spa
刪除:.net
咱們能夠「惰性刪除」,即沿着路徑查找到葉節點後,直接刪除葉節點,中間的非葉節點不刪除。設計
應用指針
Radix樹在Linux中的應用:htm
Linux基數樹(radix tree)是將long整數鍵值與指針相關聯的機制,它存儲有效率,而且可快速查詢,用於整數值與指針的映射(如:IDR機制)、內存管理等。
IDR(ID Radix)機制是將對象的
身份鑑別號整數值ID與對象指針創建關聯表,完成從ID與指針之間的相互轉換。IDR機制使用radix樹狀結構做爲由id進行索引獲取指針的稀疏數組,經過使用位圖能夠快速分配新的ID,IDR機制避免了使用固定尺寸的數組存放指針。IDR機制的API函數在lib/idr.c中實現。
Linux radix樹最普遍的用途是用於
內存管理,結構address_space
經過radix樹跟蹤綁定到地址映射上的核心頁,該radix樹容許內存管理代碼快速查找標識爲dirty或writeback的頁。其使用的是數據類型unsigned long的固定長度輸入的版本。每級表明了輸入空間固定位數。Linux radix樹的API函數在lib/radix-tree.c中實現。(把頁指針和描述頁狀態的結構映射起來,使能快速查詢一個頁的信息。)
Linux內核利用radix樹在文件內偏移快速定位文件緩存頁。
Linux(2.6.7) 內核中的分叉爲 64(2^6),樹高爲 6(64位系統)或者 11(32位系統),用來快速定位 32 位或者 64 位偏移,radix tree 中的每個葉子節點指向文件內相應偏移所對應的Cache項。
【radix樹爲稀疏樹提供了有效的存儲,代替固定尺寸數組提供了鍵值到指針的快速查找。】
後記對象
Radix樹與Trie樹的思想有點相似,甚至能夠把Trie樹看爲一個基爲26的Radix樹。(也能夠把Radix樹看作是Tire樹的變異)
Trie樹通常用於字符串到對象的映射,Radix樹通常用於長整數到對象的映射。
trie樹主要問題是樹的層高,若是要索引的字的拼音很長很變態,咱們也要建一個很高很變態的樹麼?
radix樹能固定層高(對於較長的字符串,能夠用數學公式計算出其特徵值,再用radix樹存儲這些特徵值)
【相關代碼能夠參考】
http://www.cnblogs.com/Bozh/archive/2012/04/15/radix.html