测试输出为:
按字典顺序输出trie树中所有的字符串 递归实现: abc abc abcd aca adac ava bda 按字典顺序输出trie树中所有的字符串 迭代实现: abc abc abcd aca adac ava bda 是否出现字符串ava:true 前缀a出现的次数:6 输出还有前缀的ab的所有字符串: abc abc abcd Process finished with exit code 0
java代码如下:
package com.liyiwen.TestTrie;
import javax.swing.tree.TreeNode;
import java.util.Stack;
/** * @author liyiwen1 * @date 2016/12/5 */ //trie树可以以非常少的,存储大量具有很多相同前缀的字符串。trie树查询比哈希表快, public class Trie {
public static void main(String[] args) {
String[] strings = new String[]{"ava", "aca", "bda", "adac", "abc","abcd", "abc"};
Trie trie = Trie.getInstance();
for (String string : strings){
trie.insert(string);
}
System.out.println("按字典顺序输出trie树中所有的字符串 递归实现:");
trie.printAllString();
System.out.println("按字典顺序输出trie树中所有的字符串 迭代实现:");
trie.printAllStringIteration();
System.out.println("是否出现字符串ava:" + trie.hasString("ava"));
System.out.println("前缀a出现的次数:" + trie.preCount("a"));
System.out.println("输出还有前缀的ab的所有字符串:");
trie.printAllStrsContainsPre("ab");
}
private int size = 26;
private TrieNode root;
private Trie() {
root = new TrieNode();
}
public static Trie getInstance() {
return new Trie();
}
public void insert(String str) {
if (null == str || str.isEmpty()) {
return;
}
TrieNode node = root;
char[] charArray = str.toCharArray();
for (char val : charArray) {
int index = val - 'a';
if (null == node.nodes[index]) {
node.nodes[index] = new TrieNode();
node.nodes[index].val = val;
} else {
node.nodes[index].passCount++;
}
node = node.nodes[index];
}
node.isEnd++;
}
//判断是否出现字符串extStr public boolean hasString(String extStr) {
if (null == extStr || extStr.isEmpty()) return false;
char[] chars = extStr.toCharArray();
TrieNode node = root;
for (char val : chars) {
int index = val - 'a';
if (null == node.nodes[index]) {
return false;
} else {
node = node.nodes[index];
}
}
return node.isEnd != 0;
}
//计算前缀出现的次数 public int preCount(String pex) {
if (null == pex || pex.isEmpty()) return 0;
TrieNode node = root;
char[] chars = pex.toCharArray();
for (char val : chars) {
int index = val - 'a';
if (null == node.nodes[index]) {
return 0;
} else {
node = node.nodes[index];
}
}
return node.passCount;
}
//输出所有的字符串,按字典顺序 public void printAllString(){
printAllString(getRoot(), "");
}
//输出所有的字符串,按字典顺序, 迭代实现 public void printAllStringIteration(){
printAllStringIteration(getRoot(), "");
}
//输入以node为根节点的树所包含的所有字符串,pre为前缀 private void printAllString(TrieNode node, String pre){
if (node == null){
return ;
}
pre = pre + node.val;
if (node.isEnd != 0){
for (int i = 0; i < node.isEnd; i++){
System.out.println(pre);
}
}
for (TrieNode node1 : node.nodes){
printAllString(node1, pre);
}
}
private static class Pair{
private TrieNode node;
private String pre;
public TrieNode getNode() {
return node;
}
public void setNode(TrieNode node) {
this.node = node;
}
public String getPre() {
return pre;
}
public void setPre(String pre) {
this.pre = pre;
}
public Pair(TrieNode node, String pre) {
this.node = node;
this.pre = pre;
}
}
//输出含有pre前缀的所有字符串 public void printAllStrsContainsPre(String pre){
TrieNode node = getRoot();
for (char c : pre.toCharArray()){
int index = c - 'a';
if (node.nodes[index] == null){
return;
}else{
node = node.nodes[index];
}
}
for (TrieNode node1 : node.nodes){
if (node1 != null){
printAllString(node1, pre);
}
}
}
//输入以node为根节点的树所包含的所有字符串,pre为前缀, 迭代实现 private void printAllStringIteration(TrieNode node, String pre){
Stack<Pair> stack = new Stack<Pair>();
stack.push(new Pair(node, pre));
while (!stack.isEmpty()){
Pair pair = stack.pop();
node = pair.node;
pre = pair.pre;
if (node != null){
pre = pre + node.val;
if (node.isEnd != 0){
for (int i = 0; i < node.isEnd; i++){
System.out.println(pre);
}
}
for (int i = node.nodes.length - 1; i >= 0; i--){
stack.push(new Pair(node.nodes[i], pre));
}
}
}
}
//前序遍历Trie树 public void preOrderTraverse() {
preOrderTraverse(getRoot());
}
private void preOrderTraverse(TrieNode node) {
if (node != null) {
System.out.print(node.val + "-");
for (TrieNode sonNode : node.nodes) {
preOrderTraverse(sonNode);
}
}
}
private TrieNode getRoot() {
return root;
}
private class TrieNode {
private int passCount;
private int isEnd;
private TrieNode[] nodes;
private char val;
public TrieNode() {
passCount = 1;
isEnd = 0;
nodes = new TrieNode[size];
}
}
}