<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Algorithms and Stuff &#187; Trie class</title>
	<atom:link href="http://blog.ivank.net/tag/trie-class/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.ivank.net</link>
	<description>Algorithms and Stuff</description>
	<lastBuildDate>Thu, 14 Mar 2013 18:36:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Trie implementation in AS3</title>
		<link>http://blog.ivank.net/trie-in-as3.html</link>
		<comments>http://blog.ivank.net/trie-in-as3.html#comments</comments>
		<pubDate>Thu, 25 Nov 2010 15:27:23 +0000</pubDate>
		<dc:creator>Ivan Kuckir</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[draw]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[implementation]]></category>
		<category><![CDATA[Trie]]></category>
		<category><![CDATA[Trie algorithms]]></category>
		<category><![CDATA[Trie class]]></category>
		<category><![CDATA[visualisation]]></category>

		<guid isPermaLink="false">http://blog.ivank.net/?p=32</guid>
		<description><![CDATA[In this post, we will implement the Trie data structure in ActionScript 3. Then we will draw it to get a nice picture of this data structure. What Trie is Let&#8217;s say, our program gets a thousand words, which we have to store into some data structure. After, we will recieve requests, whether some word [...]]]></description>
			<content:encoded><![CDATA[<p>In this post, we will implement the Trie data structure in ActionScript 3. Then we will draw it to get a nice picture of this data structure.</p>
<p><span id="more-32"></span></p>
<p><object data="http://www.ivank.net/blogspot/en/TrieDrawing.swf" height="450" type="application/x-shockwave-flash" width="650"><param name="movie" value="http://www.ivank.net/blogspot/en/TrieDrawing.swf" /></object>  </p>
<h2>What Trie is</h2>
<p>Let&#8217;s say, our program gets a thousand words, which we have to store into some data structure. After, we will recieve requests, whether some word is contained in this set. If we store these words in linear array, it will be very unefficient (large memory and long running time when searching for a word). The model of Trie is more efficient. Read more on <a href="http://en.wikipedia.org/wiki/Trie">Wikipedia page</a>.</p>
<h2>Class TNode</h2>
<h3>Whad do I want</h3>
<p>I want an ability to easily create a Trie (var trie = new &#8230;), easily add words (trie.AddWord(&#8220;ahoj&#8221;);). Easily detect, whether my trie contains some word (if(trie.Contains(&#8220;hello&#8221;)) &#8230;).  </p>
<h3>How to store children in trie node</h3>
<p>Each node can have multiple children, their count is from 0 up to length of an alphabet. Alphabets are often very long  (26 &#8211; small letters, 256 &#8211; ASCII characters, $2^{16}, 2^{24}, 2^{32}$ &#8211; Unicode characters). But nodes mostly don&#8217;t have all the children from an alphabet. I decided to have a fixed-length array and to hash pointers into it. In the example below, I have an array of 4 pointers, I store the pointer on [char code] mod 4. When collision happens, I put pointers into a linked list.</p>
<p>
<img height="200" src="http://www.ivank.net/blogspot/tnode.png" width="250" />  </p>
<h3>Basic class</h3>
<pre name="dlhl" class="js">package
{
   public class TNode
   {
      // the array of 4 children of this node
      public var cn:Vector.&lt;TNode&gt; = new Vector.&lt;TNode&gt;(4, true);
      public var c:String;   // character stored in the node
      public var next:TNode; // pointer to the next node (in linked list)
      public var isEnd:Boolean = false; // whether there is the end of word

      public function TNode(c:String):void
      {
         this.c = c; // assign the parameter to "c"
      }
   }
}</pre>
<h3>Searching a child for a character</h3>
<p>Since children are in fixed-length array + in linked lists, it is not so easy to get them, so we write this method:</p>
<pre name="dlhl" class="js">public function GetChild(s:String):TNode
{
   // at first, take a look at the array "cn"
   var n:TNode = cn[ s.charCodeAt(0)% 4 ];
   if ( n == null) return null; // there is no child for "s"
   else    // there is some child, we loop through the linked list
      while (n.next != null)
      {
         if (n.c == s) return n;
         n = n.next;
      }
   if (n.c == s) return n; // it was at the end of LL
   return null; // it wasn't anywhere
}</pre>
<h3>Adding a word into a Trie</h3>
<p>At first, we read the first character of the word. If there already is a child for this charater, we add the rest of the word to this child. If not, we create a new node and add the rest of the word into it.</p>
<pre name="dlhl" class="js">public function AddWord(s:String):void
{
   // look for child for this char
   var n:TNode = GetChild(s.charAt(0));
   if(n==null) // there is no child
   {
      n = new TNode(s.charAt(0)); // we chreate one
      var pos:int = s.charCodeAt(0)% 4; // where should it be
      if(cn[pos] == null) cn[pos] = n;  // free position
      else // not free - add it to LL
      {
         var no:TNode = cn[ pos ];
         while(no.next != null) no = no.next;
         no.next = n;
      }
   }
   // add the rest of the word to it or set the flag
   if(s.length&gt;1) n.AddWord(s.substring(1,s.length));
   else n.isEnd = true; // end of the word
}</pre>
<h3>Does Trie contain the word</h3>
<pre name="dlhl" class="js">public function Contains(s:String):Boolean
{
   // at the end of recursion we return isEnd
   if(s.length == 0) return isEnd;
   // we look at the proper child
   var n:TNode = GetChild(s.charAt(0));
   if(n==null) return false; // no such child
   else return n.Contains(s.substring(1,s.length)); // ask the child
}</pre>
<h2>Drawing a trie</h2>
<p>We draw a Trie using very common code as when I was drawing <a href="http://blog.ivank.net/binary-search-tree-in-as3.html">Binary search tree</a>.  </p>
<pre name="dlhl" class="js">function drawTrie(n:TNode, x:int, y:int, w:int, place:Sprite)
{
   var i:int;
   // at first, we add chilren to array
   var nodes:Array = new Array();
   for(i = 0; i&lt;4; i++)
   {
      var no:TNode = n.cn[i]; if(no == null) continue;
      while(no != null){ nodes.push(no); no = no.next;}
   }
   var sW:int = w/nodes.length; // width for each node
   for (i = 0; i &lt; nodes.length; i++)
   {
      with(place.graphics)  // line to child
      {
         lineStyle(3,0x00E1FF);
         moveTo(x, y);
         lineTo(x-w/2 + i*sW + sW/2, y+60);
      }
      // drawing a child
      drawTrie(nodes[i], x-w/2 + i*sW + sW/2, y+60, sW, place);
   }

   // draw a round for this node
   with(place.graphics)
   {
      if(n.isEnd) lineStyle(4, 0x000000); // když je koncový
      else lineStyle(2, 0x333333);  // když není - tenčí okraj
      beginFill(0x6D00D9);
      drawEllipse(x-14, y-14, 28, 28);
      endFill();
   }

   // add text field with character
   var tf:TextField = new TextField();
   tf.text = n.c; tf.x = x-tf.textWidth; tf.y = y-14;
   place.addChild(tf);
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.ivank.net/trie-in-as3.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
