索引
其實在計算機中我們早已接觸過跟索引有關的東西,比如數據庫里的索引(index),還有硬盤文件系統中其實也有類似的東西,簡而言之,索引是一種為了方便找到自己需要的東西而設計出來的條目,你可以通過找索引找到自己想要內容的位置。索引過程是: 關鍵字->索引->文檔。在圖書館內的書分門別類,就是一種按類別來分的索引。當然索引還有很多其他的實現。
僅僅有索引的概念是不夠的。雖然分門別類是一種方法,但是我們在擁有一堆文檔的時候必須要有從文檔到索引的規范過程,並且索引的結構要提供快速查找的功能。面對一條長長的沒有處理的索引列表,甚至還沒有排好序,你可能要用O(N)的時間去看,頭都大了。
為了滿足這個要求,B+樹,哈希表可以是比較好的選擇,它們的復雜度分別是O(log N) 和 O(1)。
但是事實上為了滿足特殊的要求,有些時候還要設計更加特殊的數據結構,比如后綴樹組和trie樹用來處理非文本的序列子串搜索。
在主要的搜索引擎中,還是靠文本搜索,而索引的設計其實並不固定,還要跟搜索策略結合,這些都是搜索引擎的部分。
倒排索引
倒排索引是索引的子集。在搜索引擎之中,正排索引跟倒排索引其實都有應用。
正排索引:知道文檔d,得到d的關鍵字的位置序列,實現方式是 文檔編號+關鍵字數組
倒排索引:知道關鍵字w,找到包含關鍵字的文檔d1,d2,d3.... 實現方式是:關鍵字key做鍵的字典,值是文檔編號數組
無論是哪一種索引,都要用一種能夠快速檢索的數據結構的來實現,否則它們都會面臨大規模甚至超大規模的數據下無法工作的問題。
哈希表
哈希表,根據鍵找到值,復雜度為O(1)。它的實現是一組桶,每個桶=頭部鍵+尾部鏈表。數據結構課程中對哈希表已經講得很清楚了。它的問題在於空間消耗太大,而且可能會有哈希分配不平衡的問題。
跳表
參考一下 https://juejin.im/post/587c6cec61ff4b006501e006
跳表是一種特殊的鏈表,又稱跳躍表,可以達到O(log N)的查詢速度。這里的圖說明了跳表的元素其實都在底層,但是可以有一些重復的層級為了方便檢索。它的問題在於怎樣平衡空間和時間效率上。
跳表中用到了概率,它設定某個跳表元素的i副本出現在i+1層的概率為p,根據概率對每個值求和得到元素k的期望出現次數 (∑p^k=1/(1-p), k = 1,2,...)。現實中並不會完全按照概率來進行設計,而是用一個固定的步長來設計多級的並聯鏈表。
結論
倒排索引和跳表是為了方便檢索和加快速度而設計的結構,並且在搜索引擎中為后續的其他操作提供了基礎。現實中經常講到的是倒排索引,以及跟它關聯的tfidf。為了實現數據的快速搜索,還需要跟具體的數據結構相結合。