亚洲成年人黄色一级片,日本香港三级亚洲三级,黄色成人小视频,国产青草视频,国产一区二区久久精品,91在线免费公开视频,成年轻人网站色直接看

具有部分關(guān)鍵字分支的前綴檢索樹的制作方法

文檔序號:6405923閱讀:150來源:國知局

專利名稱::具有部分關(guān)鍵字分支的前綴檢索樹的制作方法總的來說,本發(fā)明涉及在數(shù)據(jù)庫中使用關(guān)鍵字進(jìn)行的信息索引和定位;具體地說,是涉及一種用于索引一個數(shù)據(jù)庫的前綴搜索樹。數(shù)據(jù)庫特別是那些計(jì)算機(jī)系統(tǒng)中的數(shù)據(jù)庫中經(jīng)常出現(xiàn)的一個問題是對存貯在數(shù)據(jù)庫中的某條具體信息的搜索和定位。這種搜索通過是通過下面方法來實(shí)現(xiàn)的即先為數(shù)據(jù)庫建立一個目錄(或叫索引),然后使用搜索關(guān)鍵字在索引中搜索從而找到數(shù)據(jù)庫中的信息的最有可能的位置的指示字。具有最普通的形式的數(shù)據(jù)庫的索引通常表現(xiàn)為一顆包括一個或多個通過分支連接在一起的結(jié)點(diǎn)的樹。每個結(jié)點(diǎn)通常包括一個或多個包含用于指導(dǎo)搜索的分支區(qū)域,每個這樣的分支區(qū)域中通常包括至另一個結(jié)點(diǎn)的指示字(或叫分支)和一個指示出位于沿該結(jié)點(diǎn)出發(fā)的分支上的信息范圍或者類型。樹以及對樹所作的任何檢索從一個稱為根結(jié)點(diǎn)的單一結(jié)點(diǎn)出發(fā),沿著各種分支節(jié)點(diǎn)向下,直到到達(dá)包括某條信息或者(更一般的情況下是)該信息的指示字的節(jié)點(diǎn)為止。與點(diǎn)有關(guān)的信息常被稱作葉子節(jié)點(diǎn)或者失敗節(jié)點(diǎn),因?yàn)闄z索的成功與否就在這一級決定。應(yīng)該指出的是,一顆樹內(nèi)的任何結(jié)點(diǎn)對于從屬于該結(jié)點(diǎn)的所有結(jié)點(diǎn)而言是根結(jié)點(diǎn),一顆樹內(nèi)的子結(jié)構(gòu)通常是指相對于上述結(jié)點(diǎn)的子樹。在對一顆樹進(jìn)行檢索過程中,每遇到一個結(jié)點(diǎn)時都應(yīng)該通過把一個或多個檢索關(guān)鍵字和存貯在該結(jié)點(diǎn)中的分支關(guān)鍵字比較而決定沿哪個方向(或叫分支)前進(jìn)。上面的比較結(jié)果將決定從屬于一個給定結(jié)點(diǎn)的分支中的哪一個將在檢索過程中的下一步中被選中。這里的檢索關(guān)鍵字最常見地都包括一個由與被檢索的一條或多條信息有關(guān)的字符或數(shù)字組成的字符串。舉個例子來說,“Search”,“tree”,“trees”和“searchtree”等可以是為了尋找“檢索樹”方面的信息而對一個數(shù)據(jù)庫索引進(jìn)行檢索用的關(guān)鍵字,而“617”和“895”則可以是檢索617區(qū)域的895交換局的所有電話號碼的關(guān)鍵字。正象下面將要講到的那樣,分支關(guān)鍵字所采用的形式取決于檢索樹的種類。在現(xiàn)有技術(shù)中有許多檢索樹結(jié)構(gòu),其中有很顯然是后來的所有樹結(jié)構(gòu)的祖先、檢索樹的最通用的形式“B-樹”。B-樹是一種多路徑樹,其中每個結(jié)點(diǎn)都具有(AoKo)……(AiKi)……(AnKn)的形式,其中的每個Ai是至該結(jié)點(diǎn)的一個子樹的指示字,每個Ki是與上述子樹有關(guān)的關(guān)鍵字值。由Ai指定的子樹中的所有關(guān)鍵字值均小于Ki+1的關(guān)鍵字值,子樹An中的所有關(guān)鍵字值均大于Kn,每個子樹Ai都可以是多路徑檢索樹。在一個結(jié)點(diǎn)決定走哪一條分支時,先把檢索關(guān)鍵字Kx與該結(jié)點(diǎn)的分支關(guān)鍵字Ki相比較,然后沿著與大于Kx的最小值關(guān)鍵字Ki相對應(yīng)的指示字Ai前進(jìn);如果Kx小于所有的關(guān)鍵字Ki,則檢索將沿指針Ao前進(jìn);如果Kx大于關(guān)鍵字Kn,則檢索將沿指針An前進(jìn)。從基本的B-樹得到的下一個變型是二進(jìn)制樹。這種樹中的每一個結(jié)點(diǎn)都具有統(tǒng)一的形式(Ai、Ki、Ai+1)。因此,二進(jìn)制樹中的每個結(jié)點(diǎn)都只包含一個分支關(guān)鍵字和二個分支,這從任何結(jié)點(diǎn)出發(fā)都只有二條(二進(jìn)制)分支。當(dāng)檢索關(guān)鍵字小于結(jié)點(diǎn)關(guān)鍵字Ki時,選擇最左端的分支Ai,當(dāng)檢索關(guān)鍵字Kx大于Ki時,則選擇最右端的分支Ai+1。B′-樹和B*-樹與B-樹基本相似,只有下列不同在B′-樹中,所有的信息或者信息指示字都只能在樹葉結(jié)點(diǎn)(即樹中的最低級結(jié)點(diǎn)上)被找到;而在B*-樹中,所有的失敗結(jié)點(diǎn)(亦即樹葉結(jié)點(diǎn))都在樹中的同一級別上。B*-樹對從屬于根結(jié)點(diǎn)和分支結(jié)點(diǎn)的分支的最小和最大數(shù)量也有具體限制。比特樹在其根結(jié)點(diǎn)和分支結(jié)點(diǎn)方面與B-樹相似,但在樹葉結(jié)點(diǎn)方面與B-樹不同比特樹在樹葉結(jié)點(diǎn)上并不存貯關(guān)鍵字;相反,樹葉結(jié)點(diǎn)上的每個指示字都有一個與它對應(yīng)的“區(qū)別位”,該“區(qū)別位”指示著分支的關(guān)鍵字與包含在根結(jié)點(diǎn)或下一個高于該樹葉結(jié)點(diǎn)的結(jié)點(diǎn)中的分支字之間的第一個不同的位。區(qū)別位是這樣產(chǎn)生的先把一個樹葉結(jié)點(diǎn)中的指示字的二進(jìn)制表達(dá)式與其根結(jié)點(diǎn)的結(jié)點(diǎn)關(guān)鍵字的二進(jìn)制表達(dá)式相比較,并且發(fā)現(xiàn)出最低階的二個關(guān)鍵字相異的二進(jìn)制數(shù)。接下來,這個數(shù)(實(shí)際上是區(qū)別數(shù)或叫相異位)被存入與指示字無關(guān)的樹葉結(jié)點(diǎn)中。檢索開始時,在樹葉結(jié)點(diǎn)這一級上,把檢索關(guān)鍵字與該樹葉的母結(jié)點(diǎn)的結(jié)點(diǎn)關(guān)鍵字相比較,從而確定檢索關(guān)鍵字與結(jié)點(diǎn)關(guān)鍵字相異的最低位,接著取出與下一階區(qū)別位有關(guān)的樹葉指示字。Trie是一種使用可變長度關(guān)鍵字值的索引樹,其中在Trie樹的任一級上的分支都只由關(guān)鍵字的一部分而不是整個關(guān)鍵字來確定。另外,Trie中任一級上的分支都只由關(guān)鍵字的相應(yīng)的順序字符來確定,也就是說,在trie中的jth級上的分支由關(guān)鍵字中的jth字符所確定。在一個Trie中檢索關(guān)鍵字值Kn時需要把Kn分解成其各個組成字符,再遵循那些由這些組成字符所確定的分支值。假如說,Kn=LINK,則第一級分支由與L部分對應(yīng)的分支確定;第二級分支由I部分確定,第三級由N確定,第四級由K確定。這就要求檢索關(guān)鍵字中所有字符在第一級上被分離成單獨(dú)的、互不相連的數(shù)類,并且每一類中都有一個第一級分支;Trie樹中包含與最長的期望檢索字中的字符數(shù)相對應(yīng)的多個級。最后要提一下的是前綴B-樹,其中每個結(jié)點(diǎn)還是具有(AoKo)……(AiKi)……(AnKn)的形式。前綴B-樹中的檢索方式與B-樹相同,只是前綴B-樹中的每個關(guān)鍵字Ki不是完整的關(guān)鍵字,而是完整關(guān)鍵字的一份子或者只是其前綴。前綴B-樹中任何子樹中每個結(jié)點(diǎn)上的關(guān)鍵字Ki都有相同的前綴,該前綴存貯在該子樹的根結(jié)點(diǎn)上。一個結(jié)點(diǎn)上的每個關(guān)鍵字Ki是從屬于該結(jié)點(diǎn)的相應(yīng)分支的子樹中所有結(jié)點(diǎn)的公共前綴。前綴B-樹也有一個二進(jìn)制變形,叫做前綴二進(jìn)制樹。這種樹中的每個結(jié)點(diǎn)只含一個分支關(guān)鍵字和二個分支,這樣,從任何結(jié)點(diǎn)出發(fā)都只有二個(“二進(jìn)制”)分支。前綴二進(jìn)制樹的檢索方法與二進(jìn)制樹相同,即根據(jù)檢索關(guān)鍵字是否小于或者大于結(jié)點(diǎn)關(guān)鍵字來決定向左還是向右分支。另外前綴二進(jìn)制樹也有比特樹變型,但這種樹中存貯在結(jié)點(diǎn)中的是區(qū)別位而不是前綴。具體地說,被存貯的值是關(guān)鍵字中的二個前綴之間不同的比特的二進(jìn)制數(shù),這就指示出了在決定向右還是向左分支時應(yīng)該測試的關(guān)鍵字位。上面描敘的現(xiàn)有的幾種檢索樹一般都用來為最普遍的信息檢索場合和最普通類型或叫類別的信息提供最佳的特性。其中有些樹可能是設(shè)計(jì)成(比方說)提供最小的樹深度,從而減少把連續(xù)的多個結(jié)點(diǎn)或結(jié)點(diǎn)組裝入系統(tǒng)存貯器所需的磁盤訪問次數(shù),或者是提供最少的檢索時間,或者是使所有檢索的檢索時間均衡化,或者是允許方便地進(jìn)行結(jié)點(diǎn)的插入和刪除。但是現(xiàn)有的樹結(jié)構(gòu)并不能為種類廣泛的信息提供最佳結(jié)構(gòu)。用舉例來說,現(xiàn)有的樹結(jié)構(gòu)在因某些信息所需而把關(guān)鍵字分成較大的部分時通常不是最佳的,對于建立和修改這些類型的關(guān)鍵字和信息的檢索樹也不能提供最佳的結(jié)構(gòu)?,F(xiàn)存的樹結(jié)構(gòu)中的另一個缺點(diǎn)是通常必須檢索到數(shù)據(jù)記錄這一級才能確定某一項(xiàng)數(shù)據(jù)項(xiàng)是否在數(shù)據(jù)庫中。另外,“所有的失敗結(jié)點(diǎn)必須在同一級別上”被描述成一種要求。這一缺陷是由樹結(jié)構(gòu)確定的固有的檢索方法引起的。正如上面所述的那樣,檢索關(guān)鍵字被和結(jié)點(diǎn)關(guān)鍵字加以比較從而確定具有最可能包括檢索字的匹配值的關(guān)鍵字值范圍的分支路徑。由于檢索是根據(jù)識別具有關(guān)鍵字值范圍的分支來進(jìn)行的,因此,在沒有實(shí)際的數(shù)據(jù)記錄的檢索中無法確定檢索關(guān)鍵字能實(shí)際上與一個數(shù)據(jù)記錄相匹配。本發(fā)明提出的前綴索引樹為現(xiàn)有技術(shù)中的上述問題和其它一些問題提供了答案。本發(fā)明特別適用于那些其關(guān)鍵字可以拆成幾個大的部分的信息。本發(fā)明的樹結(jié)構(gòu)還為建立和修改這些類型的關(guān)鍵字和信息的檢索字提供了一種經(jīng)改進(jìn)了的結(jié)構(gòu)。本發(fā)明的樹結(jié)構(gòu)在確定某一數(shù)據(jù)項(xiàng)不在一個數(shù)據(jù)庫中之前并不要求所有的檢索都進(jìn)行到數(shù)據(jù)記錄這一級。本發(fā)明的樹結(jié)構(gòu)提供了一種用于通過與存貯在數(shù)據(jù)記錄中的信息有關(guān)的關(guān)鍵字在一個數(shù)據(jù)處理系統(tǒng)中查找存貯在數(shù)據(jù)庫中的數(shù)據(jù)記錄的前綴索引樹結(jié)構(gòu)。樹中的每個結(jié)點(diǎn)均包括一個用于存貯由一個結(jié)點(diǎn)中的所有子樹所共享的關(guān)鍵字字符組成的最長的字符串構(gòu)成的、長度為P的前綴字符串的前綴字段和一個用于存貯其關(guān)鍵字由上述的前綴字符串構(gòu)成的那個數(shù)據(jù)記錄的參考的數(shù)據(jù)記錄字段。當(dāng)上述的前綴字符串是存貯在結(jié)點(diǎn)上的至少一個子樹中的多個關(guān)鍵字的前綴時,樹結(jié)構(gòu)還可以包括一個或多個分支字段。對于子集中的多個關(guān)鍵字中的每個不同的第P+1個關(guān)鍵字字綜都有一個分支字段,其中每個不同的第P+1個字符是分支字符。每個分支字段包括一個用于存貯關(guān)鍵字的第P+1個字符的分支字符字段和一個用于存貯一個含有至少一個其第P+1個字符是分支字符的關(guān)鍵字的子樹中的一個結(jié)點(diǎn)的參考。在本發(fā)明的另外幾個實(shí)施例中,每個結(jié)點(diǎn)還包括一個用于存貯與前綴字符串中的關(guān)鍵字字符數(shù)相等的一個數(shù)的裝置和一個用于存貯與各個結(jié)點(diǎn)中分支字段數(shù)相等的一個數(shù)的字段。本發(fā)明中還包括了建立和檢索本發(fā)明的前綴索引樹以及在樹中插入結(jié)點(diǎn)和從樹中刪除結(jié)點(diǎn)的方法。本發(fā)明的上述的其它一些目的、特征和優(yōu)點(diǎn)將在下面根據(jù)附圖對本發(fā)明和其實(shí)施例所作的詳細(xì)描述中清楚地體現(xiàn)出來。附圖中,圖1.是一個數(shù)據(jù)處理系統(tǒng)和一個常駐于其中的一個索引樹的示意圖,圖2.是本發(fā)明的一顆樹中的一個結(jié)點(diǎn)的示意圖,圖3.是本發(fā)明的一顆樹的示意圖,圖4A、4B和4C。是表示在一顆樹中插入結(jié)點(diǎn)的示意圖。圖5.是表示從樹中刪除結(jié)點(diǎn)的示意圖。A.數(shù)據(jù)處理系統(tǒng)中的樹(概述,見圖1)參照圖1,圖中示出了一個數(shù)據(jù)處理系統(tǒng)10和一個索引樹12,樹12被表示成常駐于系統(tǒng)10的可尋址存貯器空間中。系統(tǒng)10包括一個中央處理單元(CPU)14和一個直接尋址存貯器20。CPU14包括一個與工作寄存器18相連的算術(shù)邏輯單元(ALU)16,直接尋址存貯器20還可以包括一個高速緩沖存貯器和一個磁盤22形式的相關(guān)存貯器。樹12被表示成具有單一的根結(jié)點(diǎn)24的許多全部通過指示字或叫分支30相連的分支結(jié)點(diǎn)(簡稱結(jié)點(diǎn))26和樹葉結(jié)點(diǎn)(簡稱樹葉)28。如圖所示,分支結(jié)點(diǎn)26根據(jù)它們在樹12中的級別(亦即深度、也就是要到達(dá)一個給定結(jié)點(diǎn)必須經(jīng)過的結(jié)點(diǎn)數(shù))還能被指定。在這張樹表中,有二個1級分支結(jié)點(diǎn),每個被標(biāo)為L1結(jié)點(diǎn)26;有多個2級和3級分支結(jié)點(diǎn),每個分別被標(biāo)為L2結(jié)點(diǎn)26或者L3結(jié)點(diǎn)26;有一個4級分支結(jié)點(diǎn),被標(biāo)為L4結(jié)點(diǎn)26。樹12在圖1中相對于系統(tǒng)10的位置還表示出了樹12的各個單元在系統(tǒng)10的地址空間中的位置,從系統(tǒng)10向右指向的箭頭指出了系統(tǒng)10的地址空間中的各個區(qū)域的邊界。舉例來說,檢索開始時,如圖所示,根結(jié)點(diǎn)24(和一個或多個L1結(jié)點(diǎn)26以及一個或多個L2結(jié)點(diǎn)26)最可能位于系統(tǒng)10的CPU14的工作寄存器18中,故被ALU16直接訪問。其余的結(jié)點(diǎn)26以及也許部分樹葉28會在存貯器20中被發(fā)現(xiàn),而樹12的更深的結(jié)點(diǎn)也許會被發(fā)現(xiàn)作為文件存貯在磁盤22中。樹12的各個結(jié)點(diǎn)在系統(tǒng)10的地址空間中的位置還影響到結(jié)點(diǎn)以及存貯在結(jié)點(diǎn)中的指示字30的具體形式。舉例來說,正象下面對本發(fā)明的樹12的詳細(xì)描述中所指出的那樣,每個結(jié)點(diǎn)總是具有相同的基本形式,即一系列包括特殊格式的特殊類型的信息的字段。駐于工作寄存器18中節(jié)點(diǎn)定位在具體的寄存器中,而定位在存貯器20中的結(jié)點(diǎn)則駐在可以動態(tài)重賦值的,可以通過邏輯地址定位的物理存貯器單元中。駐于磁盤22中的結(jié)點(diǎn)將駐在磁盤文件上。駐于工作寄存器18中的結(jié)點(diǎn)的指示字30可以采取邏輯地址指示字更有可能采取具體的ALU16的寄存器識別碼的形式。定位于存貯器20中的結(jié)點(diǎn)的指針字30可以采取邏輯地址指示字的形式,這些邏輯地址指示字在與它們相應(yīng)的結(jié)點(diǎn)被訪間時被系統(tǒng)10翻譯成存貯器20的物理地址。駐于磁盤22上的結(jié)點(diǎn)的指示字30將采取文件參考碼的形式。應(yīng)該指出的是,雖然一個結(jié)點(diǎn)的各字段中所包含的信息的具體形式可能會因結(jié)點(diǎn)在系統(tǒng)10中的地址空間的位置而變化,樹12的各結(jié)點(diǎn)的功能、結(jié)構(gòu)和邏輯關(guān)系將保持不變。結(jié)點(diǎn)在系統(tǒng)10的地址空間中的位置還將影響系統(tǒng)10訪問結(jié)點(diǎn)和處理結(jié)點(diǎn)中所含的信息的速度,因此也影響系統(tǒng)10執(zhí)行檢索的速度。舉例來說,駐于工作寄存器18中的結(jié)點(diǎn)可以直接被ALU16訪問,因此,可以在較少的時間內(nèi)被處理。駐于存貯器20和任何相應(yīng)的高速緩存中的結(jié)點(diǎn)也能相當(dāng)快地被CPU14訪問,檢索時只需要等待從邏輯到物理地址的翻譯和讀入工作寄存器18造成的一個存貯器訪問周期的延時。但是,沿樹12檢索得越深,對樹12中的結(jié)點(diǎn)的訪問時間也就越大。具體說來,駐在磁盤22上的結(jié)點(diǎn)需要一次磁盤訪問操作,把讀出的文件送入存貯器20中,再送入工作寄存器18中。因此,樹12越“平”越好,亦即盡可能地多包含一些分支,把結(jié)點(diǎn)向根結(jié)點(diǎn)方向移動從而減少結(jié)點(diǎn)存取時間,具體地說是減少對樹12進(jìn)行檢索時所要求的磁盤訪問次數(shù)。把樹葉結(jié)點(diǎn)28盡可能地向上移入樹12的結(jié)構(gòu)中而不是要求所有的樹葉結(jié)點(diǎn)28處于相同的(最低)級別上,也是有好處的。正象下面要指出的那樣,本發(fā)明的樹12為一些種類廣泛的信息提供了一種途徑,并且具有上述優(yōu)點(diǎn)。B.有關(guān)本發(fā)明的樹的描述(圖2,圖3)本發(fā)明的樹12被設(shè)計(jì)成用于關(guān)鍵字因?yàn)楹推渌P(guān)鍵字其享幾個起始字符而被分成幾個大部分時的場合。樹12具有使用可變長度、字符指向型關(guān)鍵字的密集索引結(jié)構(gòu)。任何級別上的分支由關(guān)鍵字的一部分而不是由整個關(guān)鍵字所決定。樹12的結(jié)構(gòu)與構(gòu)成順序無關(guān)。本發(fā)明中的樹12是一種要么為空、要么具有大于或等于1的高度亦即包括一個或多個級別的前綴搜索樹,它滿足下列特性(ⅰ)樹中的任何結(jié)點(diǎn)都具有下列形式和類型P,S,(Pi……Pp),D,((Bi,Si)……(Bs,Ss))其中Pi(o<i<=s)表示前綴字符串,元(SiSi)(o<i<=s)分別是分支字符串和子樹T,D是至一個數(shù)據(jù)記錄的指示字;(ⅱ)前綴(Pi……Pp)中包含T(以及從屬于T的子樹)中所含的每個關(guān)鍵字所共享的起始字符組成的最長字符串;(ⅲ)D是和長度為P的關(guān)鍵字指向數(shù)據(jù)記錄的指示字,無關(guān)鍵字時為空;(ⅳ)每個Bi(o<i<=s)都是一個區(qū)別字符,它們是T中的一些關(guān)鍵字(亦即從屬于T的子樹中長度大于P的關(guān)鍵字)的P+1st字符;(ⅴ)Bi<Bi+1,o<i<s;(ⅵ)每個Si都是以屬于T的前綴檢索樹的指示字;(ⅶ)樹中由Si(o<i<s)表示的關(guān)鍵字是由T中以Bi作為P+1st字符的那些關(guān)鍵字去掉原有的P+1個字符而形成的。參照圖2,圖中是根據(jù)上面給出的定義而構(gòu)成的本發(fā)明的樹12的單結(jié)點(diǎn)(T)32的結(jié)構(gòu)和格式的示意圖。如圖所示,T32可以包含一個前綴字段(PF)34和一個數(shù)據(jù)指示字段(D)36。PF34包含一個長度為P(P1……Pp)、由從屬于結(jié)點(diǎn)T32的每個子樹的所有關(guān)鍵字所共享的字符組成的最長字符串組成的前綴;數(shù)據(jù)指示字段(D)36包含一個至具有關(guān)鍵字(P1……Pp)的數(shù)據(jù)記錄的指示字30,如果存在這樣的關(guān)鍵字和數(shù)據(jù)記錄的話。T32可以包含一個或多個分支字段(BF)38,每個分支字段38由一個用于存貯分支字符Bj和一個用于存貯相應(yīng)的分支指示字Sj和分支指示字段(BP)42組成。正如上面指出的那樣,每個Bj一個從屬于T32的子樹中的長度大于P的關(guān)鍵字中的第P+1個字符,而每個相對應(yīng)的Sj是指示該子樹的結(jié)點(diǎn)T32的指示字。最后,每個結(jié)點(diǎn)T32包括一個P字段44和一個S字段46,它們中分別包含存貯在PF34中的前綴的長度(或字符數(shù))和從屬于T32的子樹(或數(shù)據(jù)記錄)的數(shù)量(亦即結(jié)點(diǎn)T32中包含的BF32的個數(shù)。雖然P字段44和S字段46不是結(jié)點(diǎn)T32的結(jié)構(gòu)中的必需部分,它們在系統(tǒng)10對結(jié)點(diǎn)進(jìn)行處理時能提供幫助。具體地說,把PF36中包含的前綴的長度和分支字段的數(shù)量通知處理器要比讓系統(tǒng)從PF36和BF38中取出這些信息有效得多。正如下面參考圖3將要描述的那樣,本發(fā)明的樹12中的某些結(jié)點(diǎn)可以是結(jié)構(gòu)與分支結(jié)點(diǎn)T32完全相同只是不包含分支字段38(因分支為空白)的“樹葉”結(jié)點(diǎn)。參照圖3,圖中是使用“Btree”,“Binary”,“BinarySearch”,“Binarytree”,“Hashtable”,“Hashfunction”和“HashedFile”等關(guān)鍵字值的本發(fā)明的樹12。檢查本實(shí)施例中所用的關(guān)鍵字可以很明顯地看出,圖3中的樹12具有二個從屬于根結(jié)點(diǎn)的分支(或叫子樹)。一個分支包括那些關(guān)鍵字的首字符為“B”(Btree,Binary,BinarySearch及BinaryTree)的結(jié)點(diǎn),另一個分支包括那些關(guān)鍵字首字符為“H”(HashTable,HashFunction及HashedFile)的結(jié)點(diǎn)。因此,根結(jié)點(diǎn)T32A的PF34將為空值,因?yàn)橐浴癇”打頭的關(guān)鍵字和與“H”打頭的關(guān)鍵字之間設(shè)有共享公共前綴;T32的D字段36也將是空值,因?yàn)闆]有數(shù)據(jù)記錄從屬于T32A。T32A中包含一個用于包括所有以“B”打頭的關(guān)鍵字的T32A子樹的第一BF38字段和一個用于那些以字符“H”打頭的關(guān)鍵字的第二BF38?,F(xiàn)在來看第一個BF38字段,該字段中的BF40字段Bj字符將是字符“B”,因?yàn)椤癇”是對應(yīng)于子樹T32A中的關(guān)鍵字中的第P+1個字符。BP42字段中將包含一個指向子樹T32B中的第一個結(jié)點(diǎn)的Sj指示字SB。T32A中的第二個BF38字段在BC40字段中包含著字符“H”作為它的Bj,因?yàn)檫@是相應(yīng)的子樹中的關(guān)鍵字的第P+1個字符,BP42字段中的Sj指示字將是指向該子樹T32C的第一個結(jié)點(diǎn)的指示字SH。T32A中的P字段44和S字段46分別包含一個指示著T32A中的PF34字段中不包含前綴字符(即為空)的“0”和一個指示著T32A有二個“兒子”(即從P32A有二條分支)的“2”?,F(xiàn)在來考察T32B,以字符“B”打頭的關(guān)鍵字接下來將在以“t”為第二個字符的關(guān)鍵字“Btree”和以“i”作為其第二個字符向關(guān)鍵字(Binary,BinarySearch,和BinaryTree)之間發(fā)生分支。從這一結(jié)點(diǎn)發(fā)生分支的關(guān)鍵字之間沒有相同的前綴字符,因此T32B的PF34字段中包含一個空值,D字段36也是如此。T32B也有二個BF38,其中第一個具有的Bj為“i”,第二個具有的Bj為“t”;“i”和“t”是從屬于這些分支的子樹中的關(guān)鍵字的第P+1個字符。相應(yīng)的Sj指示字分別是指向結(jié)點(diǎn)T32D和T32E的指示字Si和St。T32B的P字段44和S字段46將分別包括一個指示著PF34字段不含前綴字符的“0”和一個指示著T32B有二個孩子即分支的“2”?,F(xiàn)在來看T32E,這個結(jié)點(diǎn)包含著一個數(shù)據(jù)記錄的參考,但是沒有通向其他結(jié)點(diǎn)的分支。因?yàn)檫@樣,T32E中的PF38字段為空(亦即該結(jié)點(diǎn)不包含PF38字段。T32E中的PF34字段中包含著相對應(yīng)的數(shù)據(jù)記錄的關(guān)鍵字的最后部分(在T32E的情況下為字符串“ree”)和一個包含指向該數(shù)據(jù)記錄的指針的D字段36。P字段44和S字段45分別為指示著PF34字符含有3個字符的“3”和指示著樹葉48A沒有至于樹的分支的“0”。下面來看從屬于結(jié)點(diǎn)T32B的另一個結(jié)點(diǎn)T32D。以P32D為根結(jié)點(diǎn)的子樹包含著關(guān)鍵字“Binary”,“BinarySearch”和“BinaryTree”,這些關(guān)鍵字中的前綴“B”和“i”作為前綴分別存貯在T32A和T32B的PF34字段中。這些關(guān)鍵字的所剩部分“nary”,“narySearch”和“naryTree”之間最長的相同前綴為字符串“nary”。這樣,字符串“nary”就作為字符串存貯在T32D的PF34字段中。在該子樹中的所有三個關(guān)鍵字在“nary”之后的字符各不相同,因此,T32D可以有三個分支。但是由于“nary”是關(guān)鍵字“Binary”的最后部分,因此,關(guān)鍵字“Binary”將使一個指向與該關(guān)鍵字有關(guān)的數(shù)據(jù)記錄的指示字寫入T32D的D字段36中,而不是產(chǎn)生至另一結(jié)點(diǎn)的一個分支。關(guān)鍵字“BinarySearch”和“BinaryTree”在“nary”之后還有剩余字符串,因此將從T32D上產(chǎn)生分支?!癇inarySearch”中的第P+1個字符為“S”,因此,“S”作為第一BF38中的Bj出現(xiàn),在BP字段42中也出現(xiàn)一個指向相應(yīng)的結(jié)點(diǎn)T32F的Sj指示字Ss?!癇inaryTree”中的第P+1個字符為“T”,因此,“T”將作為Bj出現(xiàn)在第二BF38中,在BP字段42中也將出現(xiàn)一個指向相應(yīng)的結(jié)點(diǎn)T32G的Sj指示字ST。T32D字段中的P字段44和S字段46中分別包含一個指示出PF34字段含有一個4個字符的字符串的“4”和一個指示著從T32D出發(fā)有二個分支的“2”。T32F和T32G在下列方面與T32E相似即這些結(jié)點(diǎn)不包含通向其他結(jié)點(diǎn)的進(jìn)一步分支,因而具有空白的(或叫空的)BF38字段,而在各自的D36字段中卻具有指向相應(yīng)的數(shù)據(jù)記錄的指示字。T32F中的PF34字段中包含字符串“earch”,它是關(guān)鍵字“BinarySearch”的末尾部分;而T32G中的PF34字段中含有字符串“ree”,它是關(guān)鍵字“BinaryTree”的最后部分。T32F的P字段44是一個“5”,因?yàn)椤癳arch”中有5個字符;T32G中的P字段44為“3”,因?yàn)椤皉ee”中有3個字符,各結(jié)點(diǎn)的S字段46均為零,指示著從這些結(jié)點(diǎn)再沒有分支?,F(xiàn)在概略地看一下由結(jié)點(diǎn)T32C、T32H、T32I和T32J組成的樹12的右側(cè)子樹。該子樹由與上面則描述的原則相同的原則構(gòu)成。包含在該子樹中的關(guān)鍵字為“HashTable”,“HashFunction”和“HashedFile”。三個關(guān)鍵字都有的字符“H”由于是出現(xiàn)在T32A的PF34中的前綴中的第P+1個字符因而包含在T32A的相應(yīng)的PF38中的Bj中。正如前面所描述過的那樣,T32A中的PF34中包含一個空字符串,原因是在從屬于T32A的二個分支之間沒有相同的前綴字符串。對這些關(guān)鍵字的余下部分“ashTable”,“ashFunction”和“ashedFile”而言,最長的共同前綴字符串為“ash”,因此,“ash”出現(xiàn)在T32C的PF34字段中。由于這三個關(guān)鍵字具有一個共同的前綴字符串“ash”,因此,從T32C出發(fā)將有三條分支。這三個關(guān)系字的余下部分去掉“ash”之后的第P+1個字符分別是“T”,“F”和“e”。因此,“T”,“F”和“e”將作為T32C中的BF38中的Bj出現(xiàn),同時出現(xiàn)的還有指向結(jié)點(diǎn)T32H,T32I和T32J的相應(yīng)的Sj指示字SF、ST和Se。T32C中的P字段44和S字段46分別包括一個表示PF34中有一個3個字符的字符串的“3”和一個表示從T32C出發(fā)有三條分支的“3”。結(jié)點(diǎn)T32H,T32I和T32J也是“樹葉”結(jié)點(diǎn),因?yàn)樗鼈冊贒字段36中含有指向數(shù)據(jù)記錄的指示字,但是沒有進(jìn)一步的分支因而也沒有BF38。T32H中的PF34字段中含有字符串“unction”,它是關(guān)鍵字“HashFunction”的余下部分;而T32I和T32J中的PF34字段中分別含有關(guān)鍵字“HashTable”和“HashedFile”的余下部分“able”和“dFile”。由于從這些結(jié)點(diǎn)沒有再出現(xiàn)分支,因此各結(jié)點(diǎn)的S字段46中為“0”,P字段44中各自為“7”,“4”和“5”,分別表示存貯在各自的PF34字段中的關(guān)鍵字的余下部分中的字符數(shù)。C.樹12的檢索為了在本發(fā)明的樹72中檢索任何給定的關(guān)鍵字值,系統(tǒng)10將象下面將要描述的那樣從根結(jié)點(diǎn)開始,沿樹12逐個結(jié)點(diǎn)向前檢索,直到到達(dá)一個失敗結(jié)點(diǎn)(一個與檢索關(guān)鍵字不匹配的結(jié)點(diǎn))或者成功地找到與檢索關(guān)鍵字相對應(yīng)的數(shù)據(jù)記錄為止。從根據(jù)點(diǎn)開始,系統(tǒng)把具有長度(或叫字符數(shù))為K的檢索字(K)與長度為P、存貯在結(jié)點(diǎn)的PF34中的前綴字符串(P)加以比較,以判別該前綴是否與檢索字的至少起始字符是否匹配,也就是說,對于i<=P而言,K>=P還是Ki=Pi。這里應(yīng)該指出的是如果前綴P=0,也就是P為空字符串,則視為檢索關(guān)鍵字和前綴之間沒有字符匹配。如果檢索關(guān)鍵字K和前綴P之間完全匹配即P=K,則相應(yīng)的數(shù)字記錄由存貯在該結(jié)點(diǎn)的D字段36中的指示字指定。如果長度為P的前綴字符串和檢索關(guān)鍵字字符串中的前P個字符相匹配,系統(tǒng)檢索BF=38的BC40字段中的各個Bj,以找到一個能與關(guān)鍵字K的第P+1個字符(Kp+1)相匹配的Bj。如果在檢索中沒有發(fā)現(xiàn)Bj=Kp+1,則該結(jié)點(diǎn)中不含有此關(guān)鍵字值,檢索也就失敗。如果檢索中找到一個Bj等于Kp+1,則檢索遵循相應(yīng)的Sj指示字到達(dá)下一個結(jié)點(diǎn),并繼續(xù)進(jìn)行檢索。應(yīng)該記住的是樹中每個后續(xù)結(jié)點(diǎn)中的前綴由各關(guān)鍵字的余下部分間最長的共同前綴字符串去掉已經(jīng)結(jié)合到前面的結(jié)點(diǎn)中的前綴中前導(dǎo)前綴字符串后形成。用來檢索樹中下一個結(jié)點(diǎn)的關(guān)鍵字就具有了一個類似的新關(guān)鍵字值Kp+2……Kk,換句話說,由檢索關(guān)鍵字去掉在前面結(jié)點(diǎn)中與前綴和分支字符相匹配的那些前導(dǎo)關(guān)鍵字字符后剩下的部分構(gòu)成。在下面的示例性檢索程序清單A中,可以發(fā)現(xiàn)對檢索本發(fā)明的樹所作的更一步描述程序清單A-樹檢索procedurePSEARCH(T,(K1……Kk))∥對駐留在磁盤上的前綴檢索樹用關(guān)鍵字值(K1……Kk)進(jìn)行檢索,返回一個值(i,d);如果K不存在則i為假,不然的話i為真,d為數(shù)據(jù)記錄指示字.∥if(T=0)thenreturn(FALSE,O)∥特例樹為空∥X=T;n=0loopinputnodeXfromdiskletXdefinep,s,(p1……pp),D,((B1,S1)……(BS,SS))∥如果前綴太長,不可能與關(guān)鍵字匹配∥ifn+p>kthenreturn(FALSE,O)∥前綴與關(guān)鍵字中的幾個前導(dǎo)字符相匹配∥fori=1topdon=n+1ifKn<>Pithenreturn(FALSE,O)end∥確定該結(jié)點(diǎn)是否包含關(guān)鍵字∥ifn=kthen(ifD=nullthenreturn(FALSE,O)elsereturn(TRUE,D))∥確定下一步去哪一結(jié)點(diǎn),檢索分支字符∥n=n+1j=1loopcasej>sreturn(FALSE,O)Kn<Bjreturn(FALSE,O)Kn=Bjexitelsej=j(luò)+1endforeverX=SjforeverendPSEARCH程序清單B-結(jié)點(diǎn)插入procedurePINSERT(T,(K1……KK),d)∥把數(shù)據(jù)記錄指示字為d的關(guān)鍵字值(k……k)插入前綴檢索樹I中,d為空或者該關(guān)鍵字值已存在則返回假,否則,返回真?!蝘f(d=null)thenreturn(FALSE)∥特例d為假∥if(T=null)特例樹為空∥then(T=MAKENODE((K1……Kk),d,());return(TRUE))X=T;Y=null;y=0;n=0;j=0loopinputnodeXfromdiskletXbedefinedby(p1……pp),D,((B1,S1)……(BS,SS))∥前綴與關(guān)鍵字中的前導(dǎo)字符相匹配∥l=MIN(p,k-n)fori=1toldon=n+1ifKn<>Pithenreturn(PREFIX(d,n,(K1……K1),i,x,y,Y))end∥新關(guān)鍵字是否屬于現(xiàn)有關(guān)系字的一個子集?∥ifn=kthen(ifl=pthen(ifD<>nullthenreturn(FALSE)∥查詢情況,用d代替空指示字∥D=d;outputXtodisk;return(TRUE))return(SUBSTRING(d,n,(K1……Kk),1+1,X,y,Y)))∥確定下一步去哪個結(jié)點(diǎn),檢索分支字符∥n=n+1Y=j(luò);j=1loopcasej>sreturn(BRANCH(d,n,(K1……Kk),j,X,y,Y))Kn<Bjreturn(BRANCH(d,n,(K1……Kk),j,X,y,Y))Kn=Bjexitelsej=j(luò)+1endforeverY=X;X=SforeverD.樹的建立及結(jié)點(diǎn)的插入(圖4A、B和C)樹12的建立可以采用與在現(xiàn)有樹中插入新結(jié)點(diǎn)相同的方法來進(jìn)行,可以認(rèn)為一棵新樹的起始結(jié)點(diǎn)插在了一棵空樹上。由于這個原因,下面將著重描述在現(xiàn)有樹中插入結(jié)點(diǎn),這樣的描述也同樣適用于新樹的建立。在下列5個情況下要求在樹12中插入新結(jié)點(diǎn)(a)在前綴和一個新關(guān)鍵詞之間在其中任一字符串結(jié)束之前發(fā)生不匹配,這種情況被叫做“前綴沖突”;(b)新關(guān)鍵字比前綴長,而且該關(guān)鍵字與整個長度的前綴相匹配,但是要么沒有分支字符要么關(guān)鍵字中前綴的最后一個字符之后的下一字符不在分支字符中,這種情況叫做“分支沖突”;(c)新關(guān)鍵字比前綴短,前綴在該關(guān)鍵字的整個長度上與關(guān)鍵字相匹配,這種情況叫做“原始子串”;(d)新關(guān)鍵字的長度與前綴相等,并與前綴匹配,但是沒有與該前綴相關(guān)的數(shù)據(jù),這種情況稱為“數(shù)據(jù)沖突”;(e)樹為空樹時。先考慮第一種情況即發(fā)生前綴沖突時的情況,前綴沖突時要求產(chǎn)生三個結(jié)點(diǎn)來取代發(fā)生沖突的那個結(jié)點(diǎn),其中一個替代原先存在的那個結(jié)點(diǎn),其他二個從屬于上述結(jié)點(diǎn)。在這二個新的從屬結(jié)點(diǎn)中,一個包含關(guān)鍵字中促使匹配失敗的那個字符之外的部分,另一個包含前綴中促使匹配失敗的那個字符之外的部分。替代原有結(jié)點(diǎn)的第三個結(jié)點(diǎn)中包含原有前綴中與關(guān)鍵字相匹配的部分,并包含兩條分支,因而也包含二個BF38。一個BF38的Bj將是前綴中使匹配失敗的那個字符,相應(yīng)的Sj指向包含原始前綴的剩余部分的新結(jié)點(diǎn);另一個BF38的Bj將是關(guān)鍵予中使匹配失敗的那個字符,相應(yīng)的Sj指向包含關(guān)鍵字的剩余部分的新子結(jié)點(diǎn)。圖4A中示出了上述操作過程,其中要在一顆中包含前綴“HashFunction”的結(jié)點(diǎn)T48A上加入一個新關(guān)鍵字“HashTable”。原有的前綴和新關(guān)鍵字的起始字符串“Hash”相互匹配,而在原始前綴的“F”和新關(guān)鍵字的“T”處匹配就不成立。為此建立第一個新子結(jié)點(diǎn)T48B,其PF34中包括著前綴失敗字符之后出現(xiàn)的原始前綴部分即前綴失敗字符“F”之后的字符串“unction”。原有結(jié)點(diǎn)T84A中有一個指向一個數(shù)據(jù)記錄的D字段36指示字,因此,第一個新的子結(jié)點(diǎn)T48B中已有一個指向同一數(shù)據(jù)記錄的D字段36指示字。如果結(jié)點(diǎn)T48A中包含一個場BF38,它也應(yīng)該出現(xiàn)在新子結(jié)點(diǎn)T48B中。第二個新子結(jié)點(diǎn)T48C中的PF34中包含有關(guān)鍵字在關(guān)鍵字失敗字符之后出現(xiàn)的部分,即關(guān)鍵字失敗字符“T”之后出現(xiàn)的字符串“able”。第二新子結(jié)點(diǎn)T48C中也包括一個指向與關(guān)鍵字“HashTable”有關(guān)的數(shù)據(jù)記錄的D字段36指示字。最后,替代原結(jié)點(diǎn)T48A的新結(jié)點(diǎn)T48D的PF34中具有字符串“Hash”,即前綴和關(guān)鍵字字符串之間匹配的部分。新結(jié)點(diǎn)T48D的第一BF38中包含一個Bj“F”(它是造成不匹配的前綴字符)和一個指向具有前綴“unction”(原有前綴的余下部分)的新子結(jié)點(diǎn)的相應(yīng)的Sj指示字。新結(jié)點(diǎn)T48D中的第二BF38的Bj中包含造成不匹配的關(guān)鍵字字符“T”,并且包含一個指向具有前綴“able”(關(guān)鍵字的余下部分)的相應(yīng)的Sj指示字。雖然原來的結(jié)點(diǎn)T48A中有一個指向一個數(shù)據(jù)記錄的D字段36指示字,但這個指示字現(xiàn)已出現(xiàn)在第一個子結(jié)點(diǎn)T48B中,因此這個原結(jié)點(diǎn)T48A的替代物中就沒有D字段36指示字。接下來考慮分支沖突的情況,分支沖突需要建立二個結(jié)點(diǎn)來取代發(fā)生沖突的結(jié)點(diǎn);其中一個結(jié)點(diǎn)是子結(jié)點(diǎn),其PF34中包含關(guān)鍵字中原始結(jié)點(diǎn)的分支字符Bj中未發(fā)現(xiàn)的那個字符以外的部分;另一個新結(jié)點(diǎn)中包含發(fā)生分支沖突的那個原有結(jié)點(diǎn)中的前綴、分支字符和子樹,還增加一個分支字符Bj,這個新的分支字符是原有結(jié)點(diǎn)中作為分支字符未被找到的那個關(guān)鍵字字符。與這個新的分支字符有關(guān)的還有一個指向新的子結(jié)點(diǎn)的Sj指示字。圖4B中示出了上述操作,其中要在圖4A所示的操作產(chǎn)生的樹中加入一個新關(guān)鍵字“HasheolFile”。新關(guān)鍵字“HasheolFile”比結(jié)點(diǎn)T48D的前綴“Hash”長,并與整個前綴相匹配。但是該關(guān)鍵字的下一個字符“e”卻未在T48D的BF38中發(fā)現(xiàn)。因此,要生成一個新結(jié)點(diǎn)T48E,該結(jié)點(diǎn)的PF34中應(yīng)包括關(guān)鍵詞在未被發(fā)現(xiàn)的分支字符“e”之后的部分“dFile”作為前綴。為具有分支字符“e”的T48D生成一個相應(yīng)的新的BF38和指向新結(jié)點(diǎn)T48E的相應(yīng)的Sj指示字。應(yīng)該注意的是新結(jié)點(diǎn)T48E中包含一個指向與關(guān)鍵字“HashedFile”有關(guān)的數(shù)據(jù)記錄的D字段36指示字,而結(jié)點(diǎn)T48D和T48C則保持不變?,F(xiàn)在一個起始子串的情況,當(dāng)遇到一個起始子串時,則需建立二個結(jié)點(diǎn)來取代檢測到?jīng)_突的那個結(jié)點(diǎn)。第一個結(jié)點(diǎn)除了包括原有結(jié)點(diǎn)的子樹和分支字符外還在某PF34中包含前綴中與關(guān)鍵字不匹配的部分減去首字符。另一結(jié)點(diǎn)的PF34中包含與關(guān)鍵字匹配的前綴部分加上關(guān)鍵字中的失配部分的首字符作為其唯一的分支字符,該結(jié)點(diǎn)還包含指向前一結(jié)點(diǎn)(它是這個第二結(jié)點(diǎn)的子結(jié)點(diǎn))的相應(yīng)的Sj指示字。圖4C中示出了上述操作,圖中要在具有前綴“BinarySearch”和指向一個數(shù)據(jù)記錄的D字段36指示字的結(jié)點(diǎn)T48F中加入關(guān)鍵字“Binary”。關(guān)鍵字和前綴共有的字符串“Binary”互相匹配,而前綴的“Search”部分與關(guān)鍵字不匹配。因此,要建立一個新結(jié)點(diǎn)T48F,該結(jié)點(diǎn)的前綴是與關(guān)鍵字不匹配的原始前綴部分減去其首字符“S”后的字符串“earch”。T48F也有一個D字段36指針指向與原有結(jié)點(diǎn)有關(guān)的數(shù)據(jù)記錄。如果T48F中有指向該樹的其它結(jié)點(diǎn)的分支字符和分支指示字,這些分支字符和指示字應(yīng)重現(xiàn)在新結(jié)點(diǎn)T48G中。第二個新結(jié)點(diǎn)T48H是由前綴“Binary”(原有前綴中與關(guān)鍵字相匹配的部分)和單獨(dú)的分支字符“S”(原有前綴中與關(guān)鍵字不匹配的那部分的首字符)構(gòu)成的。與分支字符“S”有關(guān)的還有一個指向新結(jié)點(diǎn)T48G的Sj指示字;T48H中包含著一個指向與關(guān)鍵字“Binary”有關(guān)的任何數(shù)據(jù)記錄的D字段36指示字。最后是數(shù)據(jù)沖突和空樹的情況,如上所述,在數(shù)據(jù)沖突中,新關(guān)鍵字的長度等于前綴的長度,關(guān)鍵字與前綴相匹配但是卻沒有與該前綴相關(guān)的數(shù)據(jù)。數(shù)據(jù)沖突可以簡單地通過向結(jié)點(diǎn)中加入數(shù)據(jù)和用指向上述數(shù)據(jù)記錄的D字段36指示字來改變結(jié)點(diǎn)的方法來處理??諛鋾r的情況更直接。系統(tǒng)可以通過(比方說)選擇多個提供最長的公共前綴的關(guān)鍵字來為樹選出一個適當(dāng)?shù)臉浣Y(jié)點(diǎn)前綴的方法來建立一個起始結(jié)點(diǎn),然后根據(jù)上面描述的方法來進(jìn)一步增加結(jié)點(diǎn)。在下面的示例性插入程序清單B中可以發(fā)現(xiàn)對上述的結(jié)點(diǎn)插入方法的進(jìn)一步描述前綴沖突時的插入procedurePREFIX(d,n,(K1……Kk),i,X,y,Y)∥在結(jié)點(diǎn)的前綴部分中發(fā)生沖突,形成三個新結(jié)點(diǎn)U.V.W,來取代發(fā)生沖突的結(jié)點(diǎn)X,K和P為沖突字符Y是X的原結(jié)點(diǎn)Y的子樹∥whichpointstoX∥假定X,Y已在貯器中∥letXdefinep,s,(P1……Pp),D,((B1,S1)……(BS,SS))letYdefineYp,Ys,(YP1……YPp),YD,((YB1,YS1)……(YBS,YSS))∥建立新結(jié)點(diǎn)U來保存關(guān)鍵字的余下部分和其數(shù)據(jù)∥U+MAKENODE((Kn+1……Kk),(d),())∥建立新結(jié)點(diǎn)V來保存前綴的余下部分和子樹∥V=MAKENODE((Pi+1……Pp),(D),((B1,S1)……(BS,SS)))∥建立新結(jié)點(diǎn)W來保存公共前綴和新子樹∥ifKn<PithenW=MAKENODE((P1……Pi-1),(),((Kn,U),(Pi,V)))elseW=MAKENODE((P1……Pi-1),(),((Pi,V),(Kn,U)))∥.用指向W的指示字取代指向Y中的X的指示字,然后清除X∥ifY=nullthenT=Welse(YSY=W;outputYtodisk)KILLNODE(X);return(TRUE)endPREFIX分支沖突時的插入procedureBRANCH(d,n,(K1……Kk),j,X,y,Y)∥一個結(jié)點(diǎn)的分支部分發(fā)生沖突,形成二個新結(jié)點(diǎn)U和W來取代發(fā)生沖突的結(jié)點(diǎn)X,K是(B1……Bs)中未發(fā)現(xiàn)的字符.∥J提供插入點(diǎn).Y是指向X的,X的母結(jié)點(diǎn)Y中的子樹∥∥假定X,Y已在存貯器中∥letXdefinep,s,(p1……pp),D,((B1,S1)……(BS,SS))letYdefineYp,Ys,(YP1……YPp),YD,((YB1,YS1)……(YBS,YSS))∥建立新結(jié)點(diǎn)U來保存新關(guān)鍵字的余下部分和其數(shù)據(jù)∥U=MAKENODE((Kn+1……Kk),(d),())∥建立新關(guān)鍵字W來保存前綴的余下部分和子樹∥W-MAKENODE((P1……Pp),(D),((B1,S1)……(Bj-1,Sj-1),(Kn,U),(Bj,Sj)……(BS,SS)))∥用指向W的指示字取代指向Y中的X的指示字,然后清除X∥ifY=nullthenT=Welse{YSY=W;outputYtodisk}KILLNODE(X);return(TRUE)endBRANCH原始子串插入procedureSUBSTRING(d,n,(K1……Kk),i,X,y,Y)∥一個結(jié)點(diǎn)的前綴部分發(fā)生下溢,建立兩個新結(jié)點(diǎn)替代關(guān)鍵字耗盡的結(jié)點(diǎn)X.P將是下一個被檢查的字符,Y是指向的X的結(jié)點(diǎn)Y中的子樹?!渭俣╔,Y已在存貯器中l(wèi)etXdefinep,s,(p1……pp),D,((B1,S1)……(BS,SS))letYdefineYp,Ys,(YP1……YPp),YD,((YB1,YS1)……(YBS,YSS))∥建立新結(jié)點(diǎn)V來保存前綴的余下部分和子樹V=MAKENODE((Pi+1……Pp),(D),((B1,S1)……(BS,SS)))∥建立新結(jié)點(diǎn)W來保存公共前綴和新子樹∥W=MAKENODE((P1……Pi-1),(d),((pi,V)))∥用指向W的指示字取代Y中的指向的指示字X,然后清除X∥ifY=nullthenT=Welse(YSY=W;outputYtodisk)KILLNODE(X);return(TRUE)endSUBSETendPINSERTD.結(jié)點(diǎn)的刪除刪除一個包含著要被刪除的給定關(guān)鍵字的結(jié)點(diǎn)的第一步是找到那個結(jié)點(diǎn),這要求關(guān)鍵字與前綴完全匹配,接著判定是否有一個與該結(jié)點(diǎn)相關(guān)的數(shù)據(jù)。之后,結(jié)點(diǎn)的刪除還與從屬于該結(jié)點(diǎn)的分支字符的個數(shù)即分支數(shù)有關(guān)。第一種情況是結(jié)點(diǎn)中沒有分支字符Bj,也就是說,該結(jié)點(diǎn)是一個“樹葉”結(jié)點(diǎn),由該結(jié)點(diǎn)形成的檢索樹和其子樹中沒有其他關(guān)鍵字。在這種情況下,具有與待刪除的關(guān)鍵字完全匹配的前綴的結(jié)點(diǎn)將被刪除;指向該結(jié)點(diǎn)的子樹指示字和相應(yīng)的分支字符也從母結(jié)點(diǎn)(即含有指向待刪除結(jié)點(diǎn)的指示字的結(jié)點(diǎn))中刪除掉。下一種情況是只刪除結(jié)點(diǎn)中的一個分支字符。這就是說,與關(guān)鍵字匹配的前綴為待刪除結(jié)點(diǎn)及其子樹形成的檢索樹中的至少一個其他關(guān)鍵字的前導(dǎo)字符。待刪除的結(jié)點(diǎn)有效地起到了一個倉庫(Placeholder)的作用,因?yàn)樵摻Y(jié)點(diǎn)及其子樹形式的檢索樹中保存的關(guān)鍵字和其他關(guān)鍵字的所有分支點(diǎn)都將出現(xiàn)在從屬于該結(jié)點(diǎn)的子樹中的結(jié)點(diǎn)中。關(guān)鍵字的刪除步驟如下首先刪除掉包含著匹配的前綴的結(jié)點(diǎn)相關(guān)的數(shù)據(jù)記錄,即由該結(jié)點(diǎn)的D字段36指示字所指定的數(shù)據(jù)記錄。下一步必須保留待刪除結(jié)點(diǎn)的各個子結(jié)點(diǎn)與該樹的其余部分之間的連接或分支連接。這是通過把待刪除結(jié)點(diǎn)的前綴和分支字符與子結(jié)點(diǎn)的前綴加以合并,從而產(chǎn)生一個新的結(jié)點(diǎn)來替代待刪除束點(diǎn)以及從屬于該結(jié)點(diǎn)的各個子結(jié)點(diǎn)的方法來實(shí)現(xiàn)的。新結(jié)點(diǎn)事實(shí)上取代了被刪除了的結(jié)點(diǎn),并被原先指向被刪結(jié)點(diǎn)的、被刪結(jié)點(diǎn)的母結(jié)點(diǎn)中的分支指示字所指示。圖5中示出了刪除只有一個分支的一個結(jié)點(diǎn)時的情形。其中左邊的的附圖表示原有的樹,右邊的附圖表示已刪掉一個結(jié)點(diǎn)的樹。如圖所示,該樹包括一個根結(jié)節(jié)T49A,具有二個分支,因有具有二個帶有各自的相應(yīng)指針的分支字符“B”和“H”?!癇”分支指示字SB走的是一條不進(jìn)行刪除操作的分支,在這里不作討論。從屬于分支字符“H”、由相應(yīng)的指示字SH所指示的分支中包含關(guān)鍵字“Hash”,“HashTable”,“HashTableFile”和“HashTableList”。結(jié)點(diǎn)T49B通過結(jié)點(diǎn)T49A中的分支字符“A”和其PF34中的前綴“ash”而包含關(guān)鍵字“Hash”,它有單獨(dú)的一個通過相應(yīng)的分支指示字ST從屬于分支字符“T”的分支和一個根據(jù)D字段36指示字的數(shù)據(jù)記錄參考。在本例中,結(jié)果49B和關(guān)鍵字“Hash”擬從樹中刪掉。結(jié)點(diǎn)49B的分支指示字ST指向結(jié)點(diǎn)T49C,結(jié)點(diǎn)T49C包含前綴“able”和二個分別帶有指向結(jié)點(diǎn)T49D和T49E的分支指示字SF和SL的分支字符“L”和“F”。結(jié)點(diǎn)T49D和T49E中分別包含前綴“ist”和“ile”以及指向數(shù)據(jù)記錄的D字段36指示字。為了刪除結(jié)點(diǎn)T49B,第一步先找到并且刪除由T49B的D字段36所指定的數(shù)據(jù)記錄。之后,必須把T49B和T49C加以合并,從而保存T49B的“孩子”一結(jié)點(diǎn)T49C,T49D和T49E的關(guān)鍵字和數(shù)據(jù)記錄參考,從而維持母結(jié)點(diǎn)T48B(亦即T49A)和T49C、T49D和T49E之間的連結(jié)。如圖5的右側(cè)部分所示,一個包含前綴“ashTable”的新結(jié)點(diǎn)T49F被建立了起來,該新結(jié)點(diǎn)中的前綴是結(jié)點(diǎn)T49B的前綴“ash”和T49C的前綴“Table”的合并。結(jié)點(diǎn)T49F具有來自結(jié)點(diǎn)T49C的二個分支字符“L”和“F”以及分別指向結(jié)點(diǎn)T49D和T49E的相應(yīng)的分支指示字SL和SF。T49A中的指向原來的、已被刪掉的結(jié)點(diǎn)T49B的分支指示字SH現(xiàn)在指向新結(jié)點(diǎn)T49D。這樣,從結(jié)點(diǎn)T49A至T49D和T49E的連接被保存了下來。在結(jié)點(diǎn)刪除的最后一種情況下,被刪除的結(jié)點(diǎn)具有多于一個的指向子結(jié)點(diǎn)的分支字符,也就是說,被刪結(jié)點(diǎn)的前綴是由該結(jié)點(diǎn)及其子樹形成的檢索樹中的至少二個其他關(guān)鍵字的前導(dǎo)字符。在這種情況下,通過刪除指向與被刪除的關(guān)鍵字有關(guān)的數(shù)據(jù)記錄的D字段36指示字的方法只從結(jié)點(diǎn)中刪掉數(shù)據(jù)。該結(jié)點(diǎn)的前綴和分支字符必須保存,因?yàn)樵摻Y(jié)點(diǎn)形成了該結(jié)點(diǎn)的子樹的二個或二個以上的關(guān)鍵字之間的分支點(diǎn)。在下面的示例性刪除程序清單C中,可以發(fā)現(xiàn)對上面的結(jié)點(diǎn)刪除操作的進(jìn)一步描述programListingC程序清單C-結(jié)點(diǎn)刪除procedurePDELETE(T,(K1……Kk))∥從前綴檢索樹T中去除關(guān)鍵字值(K……K)返回一個值(i,d),如果K不存在,i則為假。否則i為真,d為數(shù)據(jù)記錄指示字∥ifT=nullthenreturn(FALSE,null)X=T;Y=null;Y=0;Z=null;z=0;j=0;n=0loopinputnodeXfromdiskletXbedefinedbyp,s,(P1……Pp),D,((B1,S1)……(BS,SS))∥前綴與關(guān)鍵字的前導(dǎo)字符相匹配∥ifk-n<pthenreturn(FALSE,null)fori=ltopdon=n+1ifKn<>Pithenreturn(FALSE,null)end∥關(guān)鍵字與前綴匹配嗎?∥ifn=kthen(ifD=nullthenreturn(FALSE,null)d=Dcases=0callLEAF(X,y,Y,z,Z)s=1callJOIN(X,y,Y)elseD=nullendreturn(TRUE,d))∥確定下一部去哪個結(jié)點(diǎn),檢索分支子符n=n+1z=y(tǒng);y=j(luò);j=1loopcasej>sreturn(FALSE,null)Kn<Bjreturn(FALSE,null)Kn=Bjexitelsej=j(luò)+1endforeverZ=Y(jié);Y=X;X=Sjforever樹葉procedureLEAF(X,y,Y,z,Z)∥關(guān)鍵字在一個樹葉結(jié)點(diǎn)上結(jié)束,我們要刪掉這個結(jié)點(diǎn)X,以及其母結(jié)點(diǎn)中引導(dǎo)我們的分支字符和子樹指示字值,(B,S).∥∥assumeX,Y,andZarealreadyinmemoryletYdefinep,s,(p1……pp),D,((B1,S1)……(BS,SS))letZdefinezp,zs,(ZP1……ZPzp),ZD,((ZB1,ZS1)……(ZBZs,ZSZs))∥清除結(jié)點(diǎn)X.∥KILLNODE(X);∥建立一個新結(jié)點(diǎn)W來保存Y中,刪掉一個子樹后的內(nèi)容∥ifY=nullthen(T=null;return)W=MAKENODE((P1……Pp),(D),((B1,S1)……(BY-1,SY-1),(BY+1,SY+1)……(BS,SS)))∥清除Y∥KILLNODE(Y)∥replacepointertoYinzwithpointertoW∥ifZ=nullthen(T=W;return)ZSZ=W;outputZtodiskreturnendLEAF合并procedureJOIN(X,y,Y)∥關(guān)鍵字在子樹的一個結(jié)點(diǎn)上結(jié)束,建立一個新結(jié)點(diǎn)來替代這個結(jié)點(diǎn)X和子樹(B,B)的根結(jié)點(diǎn)∥∥假定X,Y和Z已在存出貯器中∥letVdefineVp,Vs,(VP1……VPvp),VD,((VB1,VS1)……(VBVs,VSVs))letXdefinep,s,(p1……pp),D,((B1,S1)……(BS,SS))letYdefineYp,YS,(YP1……YPYp),YD,((YB1,YS1)……(YBYs,YSYs))∥從子樹中把下一個結(jié)點(diǎn)讀入存貯器∥V=S1;inputnodeVfromdisk∥建立一個新結(jié)點(diǎn)W來保存X加上V減去一個子樹后的內(nèi)容∥W=MAKENODE((P1……Pp,B1,VP1……VPVp),(VD),((VB1,VS1)……(VBVs,VSVs)))∥清除結(jié)點(diǎn)V,X∥KILLNODE(X);KILLNODE(V)∥用指向W的指示字取代Y中指向X的指示字。∥ifY=nullthen(T=W;return)YSY=W;outputYtodiskreturnendJOINendPDELETE雖然本發(fā)明是根據(jù)其方法和裝置的一個最佳實(shí)施例來進(jìn)行具體描述的,應(yīng)該看到的是,本
技術(shù)領(lǐng)域
內(nèi)的熟練人員不離開后附的權(quán)利要求中定義的本發(fā)明的精神和范圍的前提下對本發(fā)明可作各種形式上、細(xì)節(jié)上和實(shí)施上的改動。權(quán)利要求1.一種在數(shù)據(jù)處理系統(tǒng)通過與存貯在數(shù)據(jù)記錄中的信息有關(guān)的關(guān)鍵字來查找存貯在一個數(shù)據(jù)庫中的數(shù)據(jù)記錄的前綴索引樹結(jié)構(gòu),該樹的每個結(jié)點(diǎn)包括·一個前綴字段,用于存貯該結(jié)點(diǎn)的所有子樹所共享的關(guān)鍵字符組成的最長字符串構(gòu)成的長度為P的前綴字符串,·一個數(shù)據(jù)記錄字段,用于存貯其關(guān)鍵字由上述的前綴字符串所構(gòu)成的數(shù)據(jù)記錄的參考,以及·當(dāng)上述的前綴字符串是存貯在該結(jié)點(diǎn)的至少一個子樹中的關(guān)鍵字的前綴時與這些子樹中的關(guān)鍵字中的每個分離的第P+1個關(guān)鍵字字符對應(yīng)的一個分支字段,其中每個分離的第P+1個字符是一個分支字符,每個分支字段包括·一個分支字符字段,用于存貯關(guān)鍵字中的第P+1個字符,·一個分支指示字,用于存貯包含至少一個其第P+1個字符是上述分支字符的關(guān)鍵字的子樹的一個結(jié)點(diǎn)的參考。2.根據(jù)權(quán)利要求1所述的前綴索引樹結(jié)構(gòu)中的結(jié)點(diǎn),其中每個結(jié)點(diǎn)還包括·一個用于存貯一個等于前綴字符串中的關(guān)鍵字字符數(shù)的數(shù)的字段,和·一個用于存貯一個等于該結(jié)點(diǎn)中的分支字段數(shù)的數(shù)的字段。3.一種用于在一個數(shù)據(jù)處理系統(tǒng)建立一個通過與存貯在數(shù)據(jù)記錄中的信息有關(guān)的關(guān)鍵字查找存貯在數(shù)據(jù)庫中的數(shù)據(jù)記錄的前綴索引樹結(jié)構(gòu)的方法,其中樹中的每個結(jié)點(diǎn)均包括下列步驟·確定一個該結(jié)點(diǎn)的所有子樹共享的關(guān)鍵字字符構(gòu)成的長度為P的最長字符串構(gòu)成的前綴字符串,·把上述的前綴字符串存貯在該結(jié)點(diǎn)的前綴字段中,當(dāng)存在其關(guān)鍵字由上述的前述字符串構(gòu)成的數(shù)據(jù)記錄時,·在該結(jié)點(diǎn)的數(shù)據(jù)記錄字段中存入其關(guān)鍵字由上述的前綴字符串構(gòu)成的數(shù)據(jù)記錄的參考,當(dāng)上述的前綴字符串是存貯在該結(jié)點(diǎn)的至少一個子樹中的多個關(guān)鍵字的前綴時,·為存貯在每個子樹中的所有關(guān)鍵字確定分支字符,其中每個分支字符是包含在該結(jié)點(diǎn)的一個子樹中的一個關(guān)鍵字的相異的第P+1個字符,·為每個分支字符建立一個分支字段,·把分支字符存入分支字段中相應(yīng)的分支字符字段中,以及·在分支字段的分支指示字字段中存入包含至少一個其第P+1個字符是分支字符的關(guān)鍵字的子樹的一個節(jié)點(diǎn)的參考。4.在根據(jù)權(quán)利要求1的前綴索引樹中使用與存貯在數(shù)據(jù)記錄中的信息有關(guān)檢索關(guān)鍵字來檢索上述的前綴索引樹以查找一個數(shù)據(jù)記錄的方法,包括下列步驟·把長度為大于P的K的檢索關(guān)鍵字與一個結(jié)點(diǎn)的前綴字符串加以比較,·當(dāng)檢索關(guān)鍵字與前綴字符串不匹配時,·中止檢索,·當(dāng)檢索關(guān)鍵字與前綴字符串完全匹配時,·從該結(jié)后的數(shù)據(jù)記錄字段中讀出參考,從而確定其關(guān)鍵字與檢索字相對應(yīng)的那個數(shù)據(jù)記錄的位置,·當(dāng)檢索關(guān)鍵字中的最初P個字符與前綴字符串匹配時,·比較該檢索關(guān)鍵字的第P+1個字符和該結(jié)點(diǎn)的分支字段的分支字符,·如果檢索關(guān)鍵字的第P+1個字符5分支字符不匹配,·中止檢索;·如果檢索關(guān)鍵字的第P+1個字符與分支字符匹配,·從分支字段的分支指示字字段中讀出包含有其第P+1個字符與檢索字的第P+1個字符相匹配的關(guān)鍵字的子樹結(jié)點(diǎn)的參考,·對于由上述分支指示字字段提供參考的其他結(jié)點(diǎn)重復(fù)上述的步驟。5.在根據(jù)權(quán)利要求1的前綴索引樹中當(dāng)關(guān)鍵字和前綴字符串在結(jié)束之前發(fā)生不匹配時在上述的前綴索引樹中的一個結(jié)點(diǎn)上加入一個新關(guān)鍵字的方法,包括下列步驟·建立第一個新結(jié)點(diǎn),該結(jié)點(diǎn)·在其前綴字段中包含關(guān)鍵字中引起關(guān)鍵字與原有前綴字符串失配的那個關(guān)鍵字字符之后的部分,·在其數(shù)據(jù)記錄字段中包含一個與新關(guān)鍵字相關(guān)的數(shù)據(jù)記錄的參考;·建立第二個新結(jié)點(diǎn),該結(jié)點(diǎn)·在其前綴字段中包含原有的前綴字符串在引起關(guān)鍵字與原有前綴失配的那個原有前綴字符之后的部分,·在其數(shù)據(jù)記錄和分支字段中包含原有接點(diǎn)的數(shù)據(jù)記錄和分支字段中的內(nèi)容;·建立一個第三新結(jié)點(diǎn),該結(jié)點(diǎn)·在其前綴字段中包含與關(guān)鍵字匹配的那部分原有前綴字符串,·包含一個第一分支字段,該字段·在其分支字符字段中具有引起原有的前綴字符串與關(guān)鍵字失配的那個關(guān)鍵字字符,·在其分支指示字字段中包含一個指向上述的新的第一結(jié)點(diǎn)的參考?!ぐㄒ粋€第二分支字段,該字段·在其分支字符字段中具有原有前綴字符串中引起原有前綴字符串與關(guān)鍵字之間失配的那個字符,·在其分支指示字字段中包含一個指向第二個新結(jié)點(diǎn)的參考。6.在權(quán)利要求1所述的前綴索引樹中,當(dāng)一個結(jié)點(diǎn)前綴字符串的長度P小于K,并且與一個新關(guān)鍵字的前P個字符相匹配,同時該結(jié)點(diǎn)中又不包括能與該關(guān)鍵字的第P+1個字符相匹配的分支字符時,在上述的前綴索引樹中的結(jié)點(diǎn)上插入一個長度為K的新關(guān)鍵字的方法,包括下列步驟·建立一個新結(jié)點(diǎn),該結(jié)點(diǎn)·在其前綴字段中包含新關(guān)鍵字中第P+1個字符之后的部分,·在其數(shù)據(jù)記錄字段中包含一個指向與該新關(guān)鍵字相關(guān)的數(shù)據(jù)記錄的參考,·在原有結(jié)點(diǎn)中,·加入一個新的分支字符字段,該字段·在其分支字符字段中包含新關(guān)鍵字的第P+1個字符,·在其分支指示字字段中包含一個指向新結(jié)點(diǎn)的參考。7.在根據(jù)權(quán)利要求1的前綴索引樹中,當(dāng)一個結(jié)點(diǎn)上的前綴字符串的長度P大于K,并且新關(guān)鍵字的前P個字符與前綴字符串匹配時,在上述前綴索引樹的結(jié)點(diǎn)上插入一個長度為K的新關(guān)鍵字的方法,包括下列步驟·建立一個第一新結(jié)點(diǎn),該結(jié)點(diǎn),·在其前綴字段中包含原有的前綴字符串的第P+1個字符之后的部分,·在其數(shù)據(jù)記錄和分支字段中包含原有結(jié)點(diǎn)的數(shù)據(jù)記錄和分支字段的內(nèi)容;·建立一個第二新結(jié)點(diǎn)來替代原有結(jié)點(diǎn),該結(jié)點(diǎn)·在其前綴字段中包含原有的前綴字符串中與檢索關(guān)鍵字相匹配的部分,·還包含一個分支字段,該字段·在其分支字符字段中包含原有前綴字符串中的第K+1個字符,·在其分支指示字字段中包含至上述的第一新結(jié)點(diǎn)的參考。8.在根據(jù)權(quán)利要求1的前綴索引樹中從中刪除掉一個關(guān)鍵字的方法,包括下列步驟·確定含有待刪關(guān)鍵字的結(jié)點(diǎn)和該結(jié)點(diǎn)的分支字符數(shù),·當(dāng)該結(jié)點(diǎn)中沒有分支字符時,·刪除掉該結(jié)點(diǎn),并且·從上述的被刪節(jié)點(diǎn)的母結(jié)點(diǎn)的分支字段中刪掉分支字符和指向被刪結(jié)點(diǎn)的分支指示字,·當(dāng)該結(jié)點(diǎn)中含有多于一個的分支字符時,·刪掉為與被刪關(guān)系字相關(guān)的數(shù)據(jù)記錄提供參考的數(shù)據(jù)記錄指示字,·當(dāng)結(jié)點(diǎn)中含有一個分支字符時,·查找由該結(jié)點(diǎn)的單一個支字段的分支指示字提供參考的子結(jié)點(diǎn),·把原有前綴字符串與子結(jié)點(diǎn)中的前綴字符串加以合并而形成一個新的前綴字符串,·從該結(jié)點(diǎn)上刪掉原有的單一分支字段,·把子結(jié)點(diǎn)上的分支字段和數(shù)據(jù)記錄字段寫入該結(jié)點(diǎn)的分支字段和數(shù)據(jù)記錄字段中。全文摘要本發(fā)明為用于通過與存貯在數(shù)據(jù)記錄中的信息有關(guān)的關(guān)鍵字來查找數(shù)據(jù)記錄的前綴樹結(jié)構(gòu)。每個結(jié)點(diǎn)包括一個前綴字段用于存貯由該結(jié)點(diǎn)的所有子樹所共享的最長的關(guān)鍵字字符(長度為P)和一個數(shù)據(jù)記錄字段用于存貯其關(guān)鍵字由前綴字串構(gòu)成的數(shù)據(jù)記錄的參考。當(dāng)前綴字符串是存貯在結(jié)點(diǎn)的至少一棵子樹中的數(shù)個關(guān)鍵詞的前綴時,一個結(jié)點(diǎn)可以包括一個或多個分支字段和用于存貯各關(guān)鍵字中的不同的第P+1個字符的分支字段。本發(fā)明中還敘述了根據(jù)本發(fā)明建立和檢索前綴索引樹的方法。文檔編號G06F17/30GK1050630SQ9010797公開日1991年4月10日申請日期1990年9月25日優(yōu)先權(quán)日1989年9月28日發(fā)明者斯蒂文·P·尼克爾申請人:布爾Hn信息系統(tǒng)公司
網(wǎng)友詢問留言 已有0條留言
  • 還沒有人留言評論。精彩留言會獲得點(diǎn)贊!
1