trie樹(前綴樹)詳解——PHP代碼實現


trie樹常用於搜索提示。如當輸入一個網址,可以自動搜索出可能的選擇。當沒有完全匹配的搜索結果,可以返回前綴最相似的可能。

一、Tire樹的基本性質

  • 根節點不包含字符,除根節點外每一個節點都只包含一個字符。
  • 從根節點到某一節點,路徑上經過的字符連接起來,為該節點對應的字符串。
  • 每個節點的所有子節點包含的字符都不相同。

Trie 樹的本質,就是利用字符串之間的公共前綴,將重復的前綴合並在一起,比如我們有[b,abc,abd,bcd,abcd,efg,hii ]這個字符串集合,可以將其構建成下面這棵 Trie 樹:

每個節點表示一個字符串中的字符,從根節點到紅色節點的一條路徑表示一個字符串(紅色節點表示是某個單詞的結束字符,但不一定都是葉子節點)。這樣,我們就可以通過遍歷這棵樹來檢索是否存在待匹配的字符串了

二、如何實現Tire樹

Tire主要包含兩個操作,一個是將字符串集合構造成 Trie 樹。這個過程分解開來的話,就是一個將字符串插入到 Trie 樹的過程。另一個是在 Trie 樹中查詢一個字符串。

Trie 樹是個多叉樹,在這里用數組來存儲一個節點的所有子結點。

Trie樹節點類,PHP代碼實現:

 1 <?php
 2 /**
 3  * TrieNode.php
 4  * Created on 2019/4/29 14:53
 5  * Created by Wilin
 6  */
 7 
 8 class TrieNode
 9 {
10     public $data;
11     public $children = [];
12     public $isEndingChar = false;
13 
14     public function __construct($data)
15     {
16         $this->data = $data;
17     }
18 }

 

Trie樹,PHP代碼實現:

 1 <?php
 2 /**
 3  * Tire.php
 4  * Created on 2019/4/29 14:57
 5  * Created by Wilin
 6  */
 7 
 8 include "TrieNode.php";
 9 
10 class Tire {
11     private $root;
12 
13     public function __construct() {
14         $this->root = new TrieNode('/'); //根節點
15     }
16 
17     public function getRoot() {
18         return $this->root;
19     }
20 
21     public function insert($text) {
22         $p = $this->root;
23         for ($i = 0; $i < mb_strlen($text); $i++) {
24             $index = $data = $text[$i];
25 
26             if (empty($p->children[$index])) {
27                 $newNode = new TrieNode($data);
28                 $p->children[$index] = $newNode;
29             }
30             $p = $p->children[$index];
31         }
32         $p->isEndingChar = true;
33     }
34 
35     public function find($pattern) {
36         $p = $this->root;
37         for ($i = 0; $i < mb_strlen($pattern); $i++) {
38             $index = $data = $pattern[$i];
39 
40             if (empty($p->children[$index])) {
41                 return false;
42             }
43             $p = $p->children[$index];
44         }
45         if ($p->isEndingChar == false) {
46             return false;
47         }
48         return true;
49     }
50 }
51 
52 $trie = new Tire();
53 $strings = ['b','abc','abd','bcd','abcd','efg','hii'];
54 foreach ($strings as $str) {
55     $trie->insert($str);
56 }
57 if ($trie->find('bcd')) {
58     print "包含這個字符串\n";
59 } else {
60     print "不包含這個字符串\n";
61 }
62 print_r($trie->getRoot());

 

打印結果如下:

E:\www\tree\3>php Tire.php
包含這個字符串
TrieNode Object
(
    [data] => /
    [children] => Array
        (
            [b] => TrieNode Object
                (
                    [data] => b
                    [children] => Array
                        (
                            [c] => TrieNode Object
                                (
                                    [data] => c
                                    [children] => Array
                                        (
                                            [d] => TrieNode Object
                                                (
                                                    [data] => d
                                                    [children] => Array
                                                        (
                                                        )

                                                    [isEndingChar] => 1
                                                )

                                        )

                                    [isEndingChar] =>
                                )

                        )

                    [isEndingChar] => 1
                )

            [a] => TrieNode Object
                (
                    [data] => a
                    [children] => Array
                        (
                            [b] => TrieNode Object
                                (
                                    [data] => b
                                    [children] => Array
                                        (
                                            [c] => TrieNode Object
                                                (
                                                    [data] => c
                                                    [children] => Array
                                                        (
                                                            [d] => TrieNode Object
                                                                (
                                                                    [data] => d
                                                                    [children] => Array
                                                                        (
                                                                        )

                                                                    [isEndingChar] => 1
                                                                )

                                                        )

                                                    [isEndingChar] => 1
                                                )

                                            [d] => TrieNode Object
                                                (
                                                    [data] => d
                                                    [children] => Array
                                                        (
                                                        )

                                                    [isEndingChar] => 1
                                                )

                                        )

                                    [isEndingChar] =>
                                )

                        )

                    [isEndingChar] =>
                )

            [e] => TrieNode Object
                (
                    [data] => e
                    [children] => Array
                        (
                            [f] => TrieNode Object
                                (
                                    [data] => f
                                    [children] => Array
                                        (
                                            [g] => TrieNode Object
                                                (
                                                    [data] => g
                                                    [children] => Array
                                                        (
                                                        )

                                                    [isEndingChar] => 1
                                                )

                                        )

                                    [isEndingChar] =>
                                )

                        )

                    [isEndingChar] =>
                )

            [h] => TrieNode Object
                (
                    [data] => h
                    [children] => Array
                        (
                            [i] => TrieNode Object
                                (
                                    [data] => i
                                    [children] => Array
                                        (
                                            [i] => TrieNode Object
                                                (
                                                    [data] => i
                                                    [children] => Array
                                                        (
                                                        )

                                                    [isEndingChar] => 1
                                                )

                                        )

                                    [isEndingChar] =>
                                )

                        )

                    [isEndingChar] =>
                )

        )

    [isEndingChar] =>
)

 

參考資料:https://www.cnblogs.com/luosongchao/p/3239521.htmlhttps://articles.zsxq.com/id_qa0npqvszcmx.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM