字典树(前缀树)的实现

在实现字典树(前缀树)之前,我们先看一下什么是字典树(前缀树)

“字典树又称前缀树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。

它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。”------百度百科

字典树是一种树形结构,优点是利用字符串的公共前缀来节约存储空间。

 字典树如图1所示:

                                             图1

在字典树上搜索添加过的单词的步骤如下:

1、从根结点开始搜索

2、取得要查找单词的第一个字母,并根据该字母选择对应的字符路径向下继续搜索。

3、字符路径指向的第二层节点上,根据第二个字母选择对应的字符路径向下继续搜索。

4、一直向下搜索,如果单词搜索完后,找到的最后一个节点是一个终止节点,比如图1中的实心节点,说明字典树中含有这个单词,

如果找到的最后一个节点不是一个终止节点,说明单词不是字典树中添加过的单词。如果单词没搜索完,但是已经没有后续的节点了,

也说明单词不是字典树中添加过的单词。

题目:字典树(前缀树)的实现:

字典树又称为前缀树或Trie树,是处理字符串常见的数据结构。假设组成所有单词的字符串是“a”~“z”,请实现字典树结构,并包含以下四个主要功能。

void insert(String word): 添加word,可以重复添加。

void delete(String word):删除word,如果word添加过多次,仅删除一个。

boolean search(String word):查询word是否在字典树中。

int prefixNumber(String pre):返回以字符串pre为前缀的单词数量。

 1 class TrieNode {
 2     int path;
 3     int end;
 4     TrieNode[] map;
 5 
 6     TrieNode() {
 7         path=0;
 8         end=0;
 9         map=new TrieNode[26];
10     }
11 }
12 class Trie {
13     private TrieNode root;
14     public Trie() {
15         root=new TrieNode();
16     }
17     public void insert(String word) {
18         if (word==null) {
19             return;
20         }
21         char[] chs=word.toCharArray();
22         TrieNode node=root;
23         node.path++;
24         int index=0;
25         for (int i=0; i<chs.length; i++) {
26             index=chs[i]-'a';
27             if (node.map[index]==null) {
28                 node.map[index]=new TrieNode();
29             }
30             node=node.map[index];
31             node.path++;
32         }
33         node.end++;
34     }
35     public void delete(String word) {
36         if (search(word)) {
37             char[] chs=word.toCharArray();
38             TrieNode node=root;
39             node.path--;
40             int index=0;
41             for (int i=0; i<chs.length; i++) {
42                 index=chs[i]-'a';
43                 node.map[index].path--;
44                 node=node.map[index];
45             }
46             node.end--;
47         }
48     }
49     public boolean search(String word) {
50         if (word==null) {
51             return false;
52         }
53         char[] chs=word.toCharArray();
54         TrieNode node=root;
55         int index=0;
56         for (int i=0; i<chs.length; i++) {
57             index=chs[i]-'a';
58             if (node.map[index]==null) {
59                 return false;
60             }
61             node=node.map[index];
62         }
63         return node.end!=0;
64     }
65     public int prefixNumber(String pre) {
66         if (pre==null) {
67             return 0;
68         }
69         char[] chs=pre.toCharArray();
70         TrieNode node=root;
71         int index=0;
72         for (int i=0; i<chs.length; i++) {
73             index=chs[i]-'a';
74             if (node.map[index]==null) {
75                 return 0;
76             }
77             node=node.map[index];
78         }
79         return node.path;
80     }
81 }

 LeetCode208实现Trie(前缀树)

题目描述:

实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:

Trie trie = new Trie();

trie.insert("apple");
trie.search("apple"); // 返回 true
trie.search("app"); // 返回 false
trie.startsWith("app"); // 返回 true
trie.insert("app");
trie.search("app"); // 返回 true
说明:

你可以假设所有的输入都是由小写字母 a-z 构成的。
保证所有输入均为非空字符串。

 1 class TrieNode {
 2     int path;
 3     int end;
 4     TrieNode[] map;
 5 
 6     TrieNode() {
 7         path=0;
 8         end=0;
 9         map=new TrieNode[26];
10     }
11 }
12 class Trie {
13     private TrieNode root;
14     public Trie() {
15         root=new TrieNode();
16     }
17     public void insert(String word) {
18         if (word==null) {
19             return;
20         }
21         char[] chs=word.toCharArray();
22         TrieNode node=root;
23         node.path++;
24         int index=0;
25         for (int i=0; i<chs.length; i++) {
26             index=chs[i]-'a';
27             if (node.map[index]==null) {
28                 node.map[index]=new TrieNode();
29             }
30             node=node.map[index];
31             node.path++;
32         }
33         node.end++;
34     }
35     public boolean search(String word) {
36         if (word==null) {
37             return false;
38         }
39         char[] chs=word.toCharArray();
40         TrieNode node=root;
41         int index=0;
42         for (int i=0; i<chs.length; i++) {
43             index=chs[i]-'a';
44             if (node.map[index]==null) {
45                 return false;
46             }
47             node=node.map[index];
48         }
49         return node.end!=0;
50     }
51     public boolean startsWith(String prefix) {
52         if (prefix==null) {
53             return false;
54         }
55         char[] chs=prefix.toCharArray();
56         TrieNode node=root;
57         int index=0;
58         for (int i=0; i<chs.length; i++) {
59             index=chs[i]-'a';
60             if (node.map[index]==null) {
61                 return false;
62             }
63             node=node.map[index];
64         }
65         return node.path!=0;
66     }
67 }

欢迎评论!!共同进步!!

(请问博客园中插入代码时“行内代码”选项是什么意思??)

原文地址:https://www.cnblogs.com/hengzhezou/p/11046886.html