Java Code Geeks

Sunday, January 25, 2009

Trie in Java

Trie is a good datastucture, details can be found here - http://en.wikipedia.org/wiki/Trie . I came across Trie while performing "Prefix" based searching. Have you ever Wondered what Data Structure is used behind the Mobile SMSes ? When we type SMS, it finishes the words or proposes what could be the end of the word. They are usually done by Trie or data structures like Trie.
Trie consumes less space so they are hot favourite data structures on PDAs or devices with less memory. Searching of a string in Trie takes around O(m) where m = length of the key. Compare it with Binary Tree which is O(logn) where n = number of elements in the tree. For a dictionary, this n could be real large.

Here is a simple implimentation of the Trie..
One class is called Node class which holds the Key and the value.



  1. public class Node {


  2. private char key;

  3. private String value;

  4. private List children;

  5. private boolean isTerminal;

  6. public boolean isTerminal() {

  7. return isTerminal;

  8. }

  9. public void setTerminal(boolean isTerminal) {

  10. this.isTerminal = isTerminal;

  11. }

  12. public Node(char key,String value)

  13. {

  14. this(key,value,new ArrayList());

  15. }

  16. public Node(char key, String value, List children) {

  17. super();

  18. this.key = key;

  19. this.value = value;

  20. this.children = children;

  21. }


  22. public char getKey() {

  23. return key;

  24. }

  25. public void setKey(char key) {

  26. this.key = key;

  27. }

  28. public String getValue() {

  29. return value;

  30. }

  31. public void setValue(String value) {

  32. this.value = value;

  33. }

  34. public List getChildren() {

  35. return children;

  36. }

  37. public void setChildren(List children) {

  38. this.children = children;

  39. }


  40. public void addChildren(Node child)

  41. {

  42. this.children.add(child);

  43. }






}

And the Main Trie class which builds the tree and finds any key...


package com.ds.trie;


  1. import java.io.BufferedReader;

  2. import java.io.File;

  3. import java.io.FileNotFoundException;

  4. import java.io.FileReader;

  5. import java.io.IOException;

  6. import java.util.ArrayList;

  7. import java.util.LinkedList;

  8. import java.util.List;

  9. import java.util.Queue;


  10. public class Trie {


  11. private Node root;

  12. private File fname;


  13. public Trie (String filename)

  14. {

  15. this.root = new Node('r',"root");

  16. this.fname = new File(filename);

  17. }


  18. public void buildTrie()

  19. {

  20. try {


  21. if (!fname.isFile())

  22. throw new FileNotFoundException("");

  23. BufferedReader f = new BufferedReader(new FileReader(fname));

  24. String key;

  25. try {

  26. while ((key = f.readLine()) != null)

  27. {

  28. // making value = full name only = key

  29. build(key,root,key);

  30. }

  31. } catch (IOException e) {

  32. // TODO Auto-generated catch block

  33. e.printStackTrace();

  34. }

  35. } catch (FileNotFoundException e) {

  36. // TODO Auto-generated catch block

  37. e.printStackTrace();

  38. }

  39. }


  40. // key = shamik

  41. private void build(String key,Node root,String value) {

  42. // TODO Auto-generated method stub

  43. char c = key.charAt(0); // c = s

  44. String tail = null;

  45. if (key.length() > 1)

  46. tail = key.substring(1); // hamik

  47. Node resultNode = findKeyinChildren(root,c); // find 's' in the children

  48. if (resultNode == null)

  49. {

  50. // this is a new key

  51. Node newNode = new Node(c,value);

  52. if (tail == null)

  53. newNode.setTerminal(true);

  54. else

  55. newNode.setTerminal(false);


  56. root.addChildren(newNode);

  57. if (tail == null)

  58. {

  59. return;

  60. }

  61. else

  62. build(tail,newNode,value);

  63. }

  64. else // got the key - s

  65. {

  66. if (tail == null)

  67. return;

  68. build (tail,resultNode,value);

  69. }

  70. }


  71. private Node findKeyinChildren(Node root, char c) {

  72. // TODO Auto-generated method stub

  73. List list = root.getChildren();

  74. if (list == null || list.size() == 0)

  75. return null;

  76. for (int i=0; i < list.size(); i++)

  77. {

  78. Node oneNode = list.get(i);

  79. if (oneNode.getKey() == c)

  80. return oneNode;

  81. }

  82. return null;

  83. }


  84. public List findKey(String key)

  85. {


  86. String value = null;

  87. List values = new ArrayList();


  88. Node resultNode = findinTrie(key,root);


  89. if (resultNode == null)

  90. {

  91. value = "Not found";

  92. values.add(value);


  93. }

  94. else

  95. {


  96. printTree(resultNode,values);


  97. }

  98. return values;


  99. }


  100. private void printTree(Node resultNode,List values) {

  101. // TODO Auto-generated method stub

  102. List list = resultNode.getChildren();


  103. if (resultNode.isTerminal())

  104. values.add(resultNode.getValue());


  105. if (list.size() == 0)

  106. {


  107. return;


  108. }

  109. else

  110. {

  111. for (int i=0; i<list.size();i++)

  112. {

  113. Node oneNode = list.get(i);

  114. printTree(oneNode,values);

  115. }

  116. }

  117. }


  118. private Node findinTrie(String key, Node root) {

  119. // TODO Auto-generated method stub

  120. // Implementing the Breath First Traversal

  121. char first = key.charAt(0);

  122. String tail = null;

  123. if (key.length() > 1)

  124. tail = key.substring(1);


  125. Node resultNode = this.findKeyinChildren(root, first);

  126. if (resultNode == null)

  127. {

  128. return null;

  129. }

  130. else

  131. {

  132. if (tail == null)

  133. return resultNode;

  134. else

  135. resultNode = findinTrie(tail,resultNode );

  136. }


  137. return resultNode;

  138. }


  139. public static void main(String[] args)

  140. {

  141. if (args.length <= 0)

  142. {

  143. System.out.println("Usage : Trie ");

  144. System.exit(1);

  145. }

  146. Trie trie = new Trie("C:\\test\\dictionary");

  147. trie.buildTrie();

  148. System.out.println("Going to look for " + args[0]);

  149. List vals = trie.findKey(args[0]);

  150. for (int i=0; i<vals.size(); i++)

  151. {

  152. System.out.println("possible value = " + vals.get(i));

  153. }


  154. }


  155. }



No comments: