Jekyll2018-07-01T21:14:29+08:00https://bambuzie.github.io/fluffy-leaf/fluffy leafSarasara.n.aladham@gmail.comCTF (Beginner Guide By A Beginner)2018-05-26T00:00:00+08:002018-05-26T00:00:00+08:00https://bambuzie.github.io/fluffy-leaf/2018/05/26/CTF(beginner%20guide)<p>On <a href="https://medium.com/@saladham/ctf-beginner-guide-by-a-beginner-3c86e4959fcc">Medium</a>. :)</p>Sarasara.n.aladham@gmail.comOn Medium. :)Heaps2018-04-02T00:00:00+08:002018-04-02T00:00:00+08:00https://bambuzie.github.io/fluffy-leaf/2018/04/02/Heaps<h2 id="definition">Definition:</h2>
<p>Heaps are a binary tree with a structural property in which all heaps are a complete binary tree (when coded we dont use linked lists with left and right pointers, rather we trace through an array and manipulating the array as if it was a complete binary tree). Heaps must also have all of its nodes in a specific order, following the heap order property. <br /></p>
<p>What makes a heap, a heap? First, ask yourself this…</p>
<!--more-->
<pre><code class="language-mermaid">graph TD
A(Is the tree <b>*</b>complete?);
A -->|Yes| B(Are the root's children >= it, a minheap, or <= it, a maxheap?);
A -->|No| C[not a heap];
B -->|Yes| D[ heap yeah!];
B -->|No| E[ not at heap];
</code></pre>
<ul>
<li>All of the levels of the tree must be filled completely except maybe the last one. <br />
|> must have the <strong>left-most</strong> nodes <strong>always</strong> filled.</li>
</ul>
<hr />
<h2 id="basic-operations">Basic Operations</h2>
<p>When we insert or delete from a heap it is important to remember to not violate any of the heap’s properties when manipulating the tree.
If we are inserting something into the tree it is important to note that we can only insert a node at the bottom(lowest) left most position in the tree.
Once we insert something into the tree you have to check and verify that it follows the heap code.</p>
<h3 id="insertion">Insertion</h3>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Here is a sample minheap
(56)
/ \
(67) (98)
/
(78)
insert(45)
(56)
/ \
(67) (98)
/ \
(78) (45) <-- lowest left most position
Now that we inserted our value or key, since the leaf node, (45), is smaller than its parent and root,
it violates the heap code and we would have to **percolate up** swap the child with its parent until
it satifies the minheap property!
(56)
/ \
(45) (98) *swaps*
/ \
(78) (67)
(45) *swaps*
/ \
(56) (98)
/ \
(78) (67)
Yay! It's a minheap again!
We continued swapping until the parent is smaller than the key we are percolating upwards.
</code></pre></div></div>
<h3 id="deletion">Deletion</h3>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Deletion example with a maxheap.
( 340 )
/ \
(230) (198)
/ \ / \
(178) (167) (145) (190)
delete(root) Note: with deletion, in order to maintain the heap structure we can only delete from
the root, we are unable to delete a random value. Generally when you want to
delete from a heap, it is always the root. Using this data structure you
cannot delete some arbitrary value.
( X ) <----- *poof* deleted
/ \
(230) (198)
/ \ / \
(178) (167) (145) (190)
( X ) *still want to follow the heap code, what should we do next?
/ \
(230) (198)
/ \ / \
(178) (167) (145) (190)
( 190 )
/ \
(230) (198)
/ \ / <--- took lowest, left leaf and placed it at the root.
(178) (167) (245)
Now that we satisfied the first property, we move onto the second strucutral property and perform some swaps
to get the max value at the root.
( 230 ) *swaps*
/ \
(190) (198)
/ \ /
(178) (167) (145)
</code></pre></div></div>
<hr />
<p>This entire time we have been representing heaps as a complete binary tree however they are implemented using an array.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+--------------+
|12|56|23|45|89|
+--------------+
0 1 2 3 4
Size: 4
Capacity: 5
Pictorially, array-to-tree conversion looks like this
(12) <--- index 0
/ \
index 1 ---> (56) (23) <--- index 2
/ \
index 3 --->(45) (89) <--- index 4
</code></pre></div></div>
<h3 id="formulas-to-know">Formulas To Know</h3>
<p>These are the formulas when figuring out the location of the parent, right and left child.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Parent(i): (i - 1) / 2
left_child(i): (i * 2) + 1
right_child(i): (i * 2) + 2
</code></pre></div></div>
<hr />
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>**Special Formula
BRMNLN(bottom right most nonleaf node): The parent of size - 1 => (i - 2) / 2
</code></pre></div></div>
<h2 id="heapsort-and-heapify">Heapsort and Heapify</h2>
<h2 id="time-and-space-complexity">Time and Space Complexity</h2>
<p>Space Complexity for a heap will always be O(n). For time complexity the worst case for Insertion and Deletion are both
O(logn) because if we insert a value that violates the heap property then the value would have to swim to the top of the heap
and perform swap operations to satisfy the property and when deleting, for the same reason due to having to perform swap
operations in order to maintain the heap property. Best case would be if the heap property has been satisfied after each operation.
Search is O(n) unless we need the max or min value which is O(1). Otherwise we would have to go through each element to see if the value exists within the
heap.</p>
<h3 id="tldr">TLDR;</h3>
<table>
<thead>
<tr>
<th>Operations</th>
<th style="text-align: left">Worst Case</th>
<th style="text-align: center">Best Case</th>
<th style="text-align: right">Average Case</th>
</tr>
</thead>
<tbody>
<tr>
<td>Insertion</td>
<td style="text-align: left">O(logn)</td>
<td style="text-align: center">O(1)</td>
<td style="text-align: right">O(logn)</td>
</tr>
<tr>
<td>Deletion</td>
<td style="text-align: left">O(logn)</td>
<td style="text-align: center">O(logn)</td>
<td style="text-align: right">O(logn)</td>
</tr>
<tr>
<td>Search</td>
<td style="text-align: left">O(n)</td>
<td style="text-align: center">O(1)</td>
<td style="text-align: right">O(n)</td>
</tr>
</tbody>
<tfoot>
<tr>
<td> </td>
<td style="text-align: left"> </td>
<td style="text-align: center"> </td>
<td style="text-align: right"> </td>
</tr>
</tfoot>
</table>
<h3 id="height">Height</h3>
<blockquote>
<p>“We define the height of a node in a tree to be the number of edges on the longest simple downward path from the node to a leaf, and we define the height of the tree to be the height of its >root. Since a heap of n elements is based on a complete binary tree, its height is (lg n). We shall see that the basic operations on heaps run in time at most proportional >to the height of the tree and thus take O(lg n) time.”</p>
</blockquote>
<blockquote>
<p><a href="http://net.pku.edu.cn/~course/cs101/2007/resource/Intro2Algorithm/book6/chap07.htm">source</a></p>
</blockquote>
<p>To visually prove this, here’s a sample <strong>complete</strong> tree.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> (46)
/ \
(57) (88)
/
(68)
Looking at the tree, it has 2 branches down from the root, the height is 2.
Mathematically when plugging in the number of nodes, n, into log(base 2)n
we get the value CEIL log(base2)4 = 2 since 2^2 = 4.
The height will always be log2(n) or (ceilLog(n+1) - 1) since the tree
is complete and can never devolve into a linked list.
Another method, much simpler, of calculating the height of a heap is the FLOOR log(base 2) of n.
</code></pre></div></div>
<h3 id="glossary-and-sources">Glossary and Sources</h3>
<blockquote>
<p><a href="http://robin-thomas.github.io/min-heap/">Traversals</a></p>
</blockquote>Sarasara.n.aladham@gmail.comDefinition: Heaps are a binary tree with a structural property in which all heaps are a complete binary tree (when coded we dont use linked lists with left and right pointers, rather we trace through an array and manipulating the array as if it was a complete binary tree). Heaps must also have all of its nodes in a specific order, following the heap order property. What makes a heap, a heap? First, ask yourself this…Tries2018-03-31T00:00:00+08:002018-03-31T00:00:00+08:00https://bambuzie.github.io/fluffy-leaf/2018/03/31/Tries<h2 id="definition"><strong>Definition:</strong></h2>
<p>A Trie is a static tree-like data structure in which each node has 26 children pointers representing the letters of the English alphabet. The strings or words can be re<strong>trie</strong>ved by traversing down a branch path of the tree. When traversing down a path the count will indicate if the string is a word and count its popularity.</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="code"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">trieNode</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">count</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">trieNode</span> <span class="o">*</span><span class="n">children</span><span class="p">[</span><span class="mi">26</span><span class="p">];</span>
<span class="p">}</span> <span class="n">trieNode</span><span class="p">;</span></pre></td></tr></tbody></table></code></pre></figure>
<!--more-->
<h3 id="advantages">Advantages</h3>
<p class="success">-Unlike a BST, trie’s do not store strings or keys associated with that node, instead its position in the tree defines what the key is linked with.<br />
-Storing strings in a BST is a O(klog(n)) where k is the length of the string and n is the total amount of strings we need to go through. Also need to take into consideration
on having to expand our array.<br />
-There are no collisions of different keys in a trie and <strong>no need to provide hash functions in a trie</strong>.<br />
-Tries use arrays and pointers - hash tables use arrays and linked lists.<br />
-Tries make it easy to search for a subset of elements, similar to BST, each time we traverse down a branch of a tree, we cut out the number of nodes we need to look at.<br />
-If we insert a dictionary of words into a BST in alphabetical order it devolves into a linked list which in turn will affect runtimes.<br />
-If using a BST it would take up extra memory since each node has two child pointers => 16 bytes <br /></p>
<h3 id="disadvantages">Disadvantages</h3>
<p class="warning">A hash takes up a lot of memory and space. <br />
Some tries can have long chains and prefixes that are not meaningful. <br /></p>
<h2 id="basic-structure">Basic Structure</h2>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>To start off, the root node of a trie is empty with 26 links (0-25)
to other nodes - one for each possible alphabetical value and so on.
The shape and structure of a trie is always a set of linked nodes,
all connecting back to an empty root node.
The root has an array of 26 pointers that all point to null at first and as the trie grows,
those pointers start to get filled up with references to other nodes and so on.
(" ")
/ | \ <---- 26 links
A..K..Z <---- Here, each node of the root are represented
as letters however when coding this up, to access
the index, need CHAR_TO_INDEX(x) ((int)x - (int)'a')
**For example** inserting the letter 'a' from "acquiesce"
will convert it to the value 0. These characters(a,b,c..)
live at those indexs(0,1,2..) since our root node will hold
an array of indexes 0 through 25, and there are 26 possible
slots for the 26 letters of the alphabet.
See conversion/reference chart.
An array representation would look like this -
+----------------------------------------------------------------------------------------------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |... | 25 |
+----------------------------------------------------------------------------------------------+
\
+-------------------------------+
| 0 |...| 14 | 15 | 16 |...| 25 | <--- malloced that shit
+-------------------------------+
/
+-------------------------------+
| 0 |...| 17 | 18 | 19 |...| 25 |
+-------------------------------+
This word spells out "kor"
The rest of the pointers are NULL.
</code></pre></div></div>
<ul>
<li>The size of a trie is directly connected to the size of the alphabet that is being represented.</li>
<li>Each node contains an array of references (as pictured above) and the characters are defined by its corresponding value, a.k.a index, in the array.</li>
<li>All the descendants of a node have a common prefix of the string associated wit that node.</li>
<li><strong>As a trie grows in size, less work must be done to add a value, since the “intermediate nodes” or branches of the trie have already been built up.</strong></li>
</ul>
<hr />
<h3 id="conversion-chart">Conversion Chart</h3>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+=======================================================================================================================+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
------------------------------------------------------------------------------------------------------------------------+
| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
+=======================================================================================================================+
</code></pre></div></div>
<h2 id="applications">Applications</h2>
<p>Tries have many uses such as storing an autocomplete dictionary, can be used as a spell checker and
store frequency of words and autocomplete senteces. For instance when you type into the Google search bar
it will autocomplete words for you based on popularity or perform a <strong>text prediction</strong> operation that will
enable the trie to fill in sentences for you based on what you recently type after a specific word.
The three common applications for using a trie; insert, deletion and search.</p>
<h3 id="text-prediction">Text Prediction</h3>
<p>Implementing text prediction would look similar to this using this corpus.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>I like dancing
I like food
She goes swimming
She likes swimming
</code></pre></div></div>
<p>Here’s what the trie looks like after inserting the words from the corpus
<img src="https://image.ibb.co/ndmN27/pic1.jpg" alt="" /></p>
<p>I color coded each leaf that correlates to the the words subtree as shown in the next photo.
This is somewhat the visual of what the word’s subtree looks like when implementing text prediction.</p>
<p><img src="http://i63.tinypic.com/20kovbq.jpg" alt="" /></p>
<h3 id="insertion">Insertion</h3>
<p>When inserting into a trie you start at the root and check to see if the character corresponding
to the index is not null, if it is that means that the word does not exist so you need to malloc
for the node until after the last letter of the string.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Example:
Word: panic
( ) <---- empty root node, malloc space at index 15
( )
\
P <---- continue the process
|
a
|
n
|
i
|
c
</code></pre></div></div>
<p>You repeat this process for insertion and if you want to insert another word that begins with ‘p’ you
start at the root node, index[15] which correlates with the character p has space so you malloc from
that node rather than the root.</p>
<p>Here’s the logic translated into code:</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre><span class="c1">// key here is our string or word
</span><span class="n">trieNode</span> <span class="o">*</span><span class="nf">insert</span><span class="p">(</span><span class="n">trieNode</span> <span class="o">*</span><span class="n">root</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">key</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">,</span> <span class="n">len</span> <span class="o">=</span> <span class="n">strlen</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">root</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="k">return</span> <span class="n">createNode</span><span class="p">();</span>
<span class="n">trieNode</span> <span class="o">*</span><span class="n">trace</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">trace</span> <span class="o">=</span> <span class="n">root</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">ALPHABET_SIZE</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">index</span> <span class="o">=</span> <span class="n">tolower</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="n">index</span> <span class="o">=</span> <span class="n">CHAR_TO_INT</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">trace</span><span class="o">-></span><span class="n">children</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="n">trace</span><span class="o">-></span><span class="n">children</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="n">createNode</span><span class="p">();</span>
<span class="n">trace</span> <span class="o">=</span> <span class="n">trace</span><span class="o">-></span><span class="n">children</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">trace</span><span class="o">-></span><span class="n">count</span><span class="o">++</span><span class="p">;</span>
<span class="k">return</span> <span class="n">root</span><span class="p">;</span>
<span class="p">}</span></pre></td></tr></tbody></table></code></pre></figure>
<p>NOTE!! CHAR_TO_INT is a defined function that I placed at the top of my program that simply looks like this -</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#define CHAR_TO_INT(c) ((int)c - (int)'a')
Takes the integer value of some char and subtracts it
by the int value of the character 'a'. If we put
quotes around the c, 'c' it would test the character c,
not an arbitrary char value which is incorrect.
</code></pre></div></div>
<p>I use this in many of my programming assignments and have found it to tremendously helpful
in scenarios when I am unable to utilize atoi. Special cases in which atoi would not work is
calling it on a character rather than a string. For instance, if *str = “123”
then atoi(str) would be 123 as an actual integer. However, atoi functionality is unable to
individually call 1 as an integer or 2 as a separate integer.</p>
<h3 id="deletion">Deletion</h3>
<p>When deleting from the trie, first you must go back and check to see if the node exists from the root and if not there is nothing to delete.
If the count is > 1 then decrement the value by one.
If the node has children just set the count back to 0.
Another thing to take into consideration when deleting from a Trie is
to go back up the chain towards the root and deleting each node in a bottom up manner (recursion) until
you hit a node with count > 0 or a node that has at least one child.</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">root</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">ALPHABET_SIZE</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="n">destroyTrie</span><span class="p">(</span><span class="n">root</span><span class="o">-></span><span class="n">children</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="n">root</span><span class="o">-></span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">free</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span></pre></td></tr></tbody></table></code></pre></figure>
<p>The deletion code above is a basic implementation of deleting all the nodes in a Trie.
NOTE! This code does not handle special cases.</p>
<p>The logic behind the code is as follows -</p>
<p>The function is recursive so you would want a base case to know when exactly to return. <br />
By doing so you would want to return when the root passed in is NULL - <br />
In order to destroy, you have to loop through each pointer from the root to see if any of the indexes are non null. <br />
From there you continue to jump to next non-null node until all of the children pointersare all null and free back up from there. <br /></p>
<p>Lets portray this -</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Some arbitrary trie
( )
/ \
( ) ( )
/
( )
NOTE!!!
> Remember that each node has 26 pointers of its own. Keep this in your mind as we move
forward with this example.
( * ) Let's use this "*" symbol as an indicator of where we are and which node we are on in the recursive call.
/ \ In the first recursive call we check to see if root == NULL. Which in this case, returns
( ) ( ) false, so we enter the forLoop.
/
( )
Call#1 has i = 0.
Make recursive call to enter the next node passing in the next next node, or in other words roots first child pointer
* - ( ) Let's use this "*" symbol as an indicator of where we are and which node we are on in the recursive call.
/ \ In the first recursive call we check to see if root == NULL. Which in this case, returns
( ) ( ) false, so we enter the forLoop.
/
( )
This child is A or index '0' in call#2 so this call will return NULL.
This pattern will continue on, and i will increment in CALL#1 until the
next call finds a nonnull child.
Once the program hits the next malloced node, i will set back to 0 and restart the whole process.
Are you starting to see the pattern here?
If so, great! So how do we know when to start deleting?
Ahh, so say you continue with the pattern as described above and you hit the very last node, eventually the looping
variable, i, will reach the limit and the loop will break. Once i = 25 and we are outside of the loop and
we are guaranteed that there are no nonnull pointers following the leaf (Hence why it's considered a leaf),
now we can start freeing!!
Once the first leaf has been freed then it will return back to the previous node.
( ) Let's use this "*" symbol as an indicator of where we are and which node we are on in the recursive call.
/ \ In the first recursive call we check to see if root == NULL. Which in this case, returns
( ) ( ) false, so we enter the forLoop.
/ \
X * <---- now remember, when we return we return back to whatever i was left off in the previous recursive call.
Since it's null from and out this node will get freed once i hits the limit.
The process repeats itself and is simply a pattern to follow up on, using the logic as applied from above.
</code></pre></div></div>
<h3 id="search">Search</h3>
<p>When searching for a string, you have to keep a couple of things in mind. <br />
A. Know how to convert the character in the string to a certain index value. *this is when the CHAR_TO_INT formula comes in handy<br />
B. Know when to exit the loop <br />
C. Know when to continue looping (move forward in the path) <br /></p>
<p>In the code below I had created a string called “s_holder” to handle cases in which the string you’re
trying to search for has special cases.</p>
<p>For tackling B and C, you would want to move forward onto the next character in the string that you are trying to search for.
Well, how do you access nodes generally?
If you recall back in the deletion example, we would loop through every individual node, null or nonNUll, hitting all the
letters in the English alphabet. But in this case we would want to look for a specific letter, using the basic format
root->children[i], what part here specifies the next letter?</p>
<p>i!</p>
<p>Therefore, supstitute i will an integer value that represents the next character and now you’re telling the program
to go to a specific node :).</p>
<p>What happens if that character doesn’t exist?
In such case, that implies the string by defualt does not exist within the Trie and will exit out immediately.
<strong>cough cough</strong> return.</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
</pre></td><td class="code"><pre> <span class="c1">// iterative search implementation
</span>
<span class="n">TrieNode</span> <span class="o">*</span><span class="nf">search</span><span class="p">(</span><span class="n">TrieNode</span> <span class="o">*</span><span class="n">root</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">str</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">root</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">str</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">TrieNode</span> <span class="o">*</span><span class="n">fishy</span> <span class="o">=</span> <span class="n">root</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">strlen</span><span class="p">(</span><span class="n">str</span><span class="p">);</span>
<span class="kt">char</span> <span class="n">s_holder</span><span class="p">[</span><span class="mi">1023</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">{};</span>
<span class="n">strcpy</span><span class="p">(</span><span class="n">s_holder</span><span class="p">,</span><span class="n">str</span><span class="p">);</span>
<span class="k">while</span><span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="n">len</span> <span class="o">&&</span> <span class="n">s_holder</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">'\0'</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">s_holder</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span>
<span class="p">{</span>
<span class="n">s_holder</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">tolower</span><span class="p">(</span><span class="n">s_holder</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="n">index</span> <span class="o">=</span> <span class="n">CHAR_TO_INT</span><span class="p">(</span><span class="n">s_holder</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fishy</span><span class="o">-></span><span class="n">children</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">fishy</span> <span class="o">=</span> <span class="n">fishy</span><span class="o">-></span><span class="n">children</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">i</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="p">(</span><span class="n">fishy</span><span class="o">-></span><span class="n">count</span> <span class="o">>=</span> <span class="mi">1</span><span class="p">)</span> <span class="o">?</span> <span class="n">fishy</span> <span class="o">:</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="p">}</span>
<span class="o">***********************************</span>
<span class="o">**</span> <span class="n">RECURSIVE</span> <span class="n">VERSION</span> <span class="n">FOR</span> <span class="n">THE</span> <span class="n">LOLS</span> <span class="o">**</span>
<span class="o">***********************************</span>
<span class="n">IMPORTANT</span><span class="o">!</span> <span class="n">This</span> <span class="n">is</span> <span class="n">the</span> <span class="n">helper</span> <span class="n">function</span> <span class="n">to</span> <span class="n">the</span> <span class="n">actual</span> <span class="n">search</span> <span class="n">function</span> <span class="n">that</span> <span class="n">would</span> <span class="n">call</span> <span class="n">this</span><span class="p">.</span>
<span class="n">TrieNode</span> <span class="o">*</span><span class="n">helper_searcher</span><span class="p">(</span><span class="n">TrieNode</span> <span class="o">*</span><span class="n">fishy</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">str</span><span class="p">,</span> <span class="kt">int</span> <span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fishy</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">str</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">strlen</span><span class="p">(</span><span class="n">str</span><span class="p">);</span>
<span class="k">while</span><span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="n">len</span> <span class="o">&&</span> <span class="n">str</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">'\0'</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">str</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span>
<span class="p">{</span>
<span class="n">index</span> <span class="o">=</span> <span class="n">CHAR_TO_INT</span><span class="p">(</span><span class="n">str</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fishy</span><span class="o">-></span><span class="n">children</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">fishy</span> <span class="o">=</span> <span class="n">fishy</span><span class="o">-></span><span class="n">children</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">i</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="p">(</span><span class="n">fishy</span><span class="o">-></span><span class="n">count</span> <span class="o">>=</span> <span class="mi">1</span><span class="p">)</span> <span class="o">?</span> <span class="n">fishy</span> <span class="o">:</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>
<h2 id="time-complexity">Time complexity</h2>
<p>Worst case runtime for a trie is dependant on how many words the trie contains and the length of each word.
In this case the time complexity would be O(m*n) with m being the longest word and n is the total number of words.
In the case of insertion all of the cases are O(k) with k being the length of the word you are trying to insert. For
deletion and search the runtime would be similar to insertion however their best case would be O(1) runtime in a
scenario a user would want to look up or delete a word that does not exist within the trie.</p>
<hr />
<h3 id="tldr">TLDR;</h3>
<table>
<thead>
<tr>
<th>Operations</th>
<th style="text-align: left">Worst Case</th>
<th style="text-align: center">Best Case</th>
<th style="text-align: right">Average Case</th>
</tr>
</thead>
<tbody>
<tr>
<td>Insertion</td>
<td style="text-align: left">O(k)</td>
<td style="text-align: center">O(k)</td>
<td style="text-align: right">O(k)</td>
</tr>
<tr>
<td>Deletion</td>
<td style="text-align: left">O(k)</td>
<td style="text-align: center">O(1)</td>
<td style="text-align: right">O(k)</td>
</tr>
<tr>
<td>Search</td>
<td style="text-align: left">O(k)</td>
<td style="text-align: center">O(1)</td>
<td style="text-align: right">O(k)</td>
</tr>
</tbody>
<tfoot>
<tr>
<td> </td>
<td style="text-align: left"> </td>
<td style="text-align: center"> </td>
<td style="text-align: right"> </td>
</tr>
</tfoot>
</table>
<blockquote>
<p>*k represents the length of the string</p>
</blockquote>
<h3 id="glossary-and-sources">Glossary and Sources</h3>
<ul>
<li><strong>Search Miss</strong>: could not find value for key</li>
<li><strong>Search Hit</strong>: able to find value for key</li>
<li><strong>Lexicon</strong>: all the valid words in the dictionary</li>
<li><strong>Corpus</strong>: body of text</li>
<li><strong>Intermediate</strong>: coming inbetween time,place,order and so on. (middle)</li>
</ul>
<hr />
<blockquote>
<p>information and references came from <a href="https://medium.com/basecs/trying-to-understand-tries-3ec6bede0014">this</a> resource.</p>
</blockquote>Sarasara.n.aladham@gmail.comDefinition: A Trie is a static tree-like data structure in which each node has 26 children pointers representing the letters of the English alphabet. The strings or words can be retrieved by traversing down a branch path of the tree. When traversing down a path the count will indicate if the string is a word and count its popularity. 1 2 3 4 5 typedef struct trieNode { int count; struct trieNode *children[26]; } trieNode;