您的位置:首页 > 理论基础 > 数据结构算法

trie树的实现和应用及测试

2016-12-07 22:32 393 查看
测试输出为:

按字典顺序输出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];
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息