<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: DINH HOANG MY LE</title>
    <description>The latest articles on DEV Community by DINH HOANG MY LE (@dinh_hoangmyle_a832c9d9).</description>
    <link>https://dev.to/dinh_hoangmyle_a832c9d9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3735929%2F0fea8ee7-481c-4d6d-abf4-9f90d85be3f7.png</url>
      <title>DEV Community: DINH HOANG MY LE</title>
      <link>https://dev.to/dinh_hoangmyle_a832c9d9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dinh_hoangmyle_a832c9d9"/>
    <language>en</language>
    <item>
      <title>What Tree Data Structure Performs Well with rank() and select()? Self-Balancing Trees with Data Augmentation</title>
      <dc:creator>DINH HOANG MY LE</dc:creator>
      <pubDate>Thu, 12 Feb 2026 16:58:58 +0000</pubDate>
      <link>https://dev.to/dinh_hoangmyle_a832c9d9/what-tree-data-structure-performs-well-with-rank-and-select-self-balancing-trees-with-data-5dk6</link>
      <guid>https://dev.to/dinh_hoangmyle_a832c9d9/what-tree-data-structure-performs-well-with-rank-and-select-self-balancing-trees-with-data-5dk6</guid>
      <description>&lt;p&gt;When you need efficient rank and select operations on dynamic data, AVL trees (or other self-balancing trees) with data augmentation are your answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are rank() and select()?
&lt;/h2&gt;

&lt;p&gt;These are fundamental order statistics operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;rank(x)&lt;/strong&gt;: Returns how many elements in the set are smaller than x (or equivalently, what position x would be if we sorted everything)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;select(k)&lt;/strong&gt;: Returns the k-th smallest element in the set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like this: if you have {3, 7, 1, 9, 5}, then rank(7) = 3 (because three elements are smaller than 7), and select(3) = 5 (the 3rd smallest element is 5).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Key Insight
&lt;/h2&gt;

&lt;p&gt;The naive approach would be to store at each node x how many nodes are smaller than x. This would make rank(x) trivial - just find x and read that value in O(log n) time. But there's a fatal flaw: this direct count is a nightmare to maintain. Every insertion or deletion could cascade updates throughout the tree, destroying the efficiency we're after.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Store Subtree Sizes Instead
&lt;/h2&gt;

&lt;p&gt;Instead of storing "how many nodes are smaller than me," each node stores "how many nodes are in my subtree (including me)." This subtle shift changes everything.&lt;/p&gt;

&lt;p&gt;Why does this work better? When you insert or delete a node, only the nodes on the path from that node to the root need their size updated - that's just O(log n) nodes in a balanced tree. The rest of the tree's size values remain valid.&lt;/p&gt;

&lt;p&gt;With subtree sizes, you can compute rank(x) by summing up the sizes of left subtrees as you traverse down to x. Similarly, select(k) works by navigating based on comparing k with subtree sizes at each step. Both operations remain O(log n).&lt;/p&gt;

&lt;p&gt;This is data augmentation at its finest: storing additional information that's cheap to maintain but powerful to query.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>performance</category>
      <category>programming</category>
    </item>
    <item>
      <title>What I’m Learning in Data Structures: The Algorithm Behind Compression (bzip, etc.)</title>
      <dc:creator>DINH HOANG MY LE</dc:creator>
      <pubDate>Wed, 11 Feb 2026 23:29:18 +0000</pubDate>
      <link>https://dev.to/dinh_hoangmyle_a832c9d9/what-im-learning-in-data-structures-the-algorithm-behind-compression-bzip-etc-20ei</link>
      <guid>https://dev.to/dinh_hoangmyle_a832c9d9/what-im-learning-in-data-structures-the-algorithm-behind-compression-bzip-etc-20ei</guid>
      <description>&lt;h1&gt;
  
  
  How Compression Algorithms Actually Work
&lt;/h1&gt;

&lt;p&gt;Today we started learning how real compression algorithms work — from simple encoding to efficient machine-level implementations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compression starts with encoding
&lt;/h2&gt;

&lt;p&gt;At first, we looked at a simple idea:&lt;/p&gt;

&lt;p&gt;If we have an array like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[a, b, c]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can encode each character using its index&lt;/p&gt;

&lt;p&gt;So the word &lt;code&gt;bba&lt;/code&gt; becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ 110

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Smarter Idea: Frequency Matters
&lt;/h2&gt;

&lt;p&gt;In English:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Some letters appear more often (e, t, a…)&lt;/li&gt;
&lt;li&gt;  Some are rare (z, q…)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we can assign shorter codes to frequent letters&lt;/p&gt;

&lt;p&gt;That's the idea behind Huffman encoding. But Huffman encoding doesn't care about patterns.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"the man in the kitchen"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The word "the" appears multiple times. Huffman treats each character independently. It doesn't care that the sequence "the" repeats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Move-to-Front (MTF)
&lt;/h2&gt;

&lt;p&gt;There is an algorithm that works well when patterns are close together. It's called &lt;strong&gt;Move-to-front (MTF)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine we have a list of all characters in order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a → b → c → d → e → f → g → h → ... → x → y → z
0   1   2   3   4   5   6   7         23  24  25

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now suppose our input string is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"xyz yy"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We process it &lt;strong&gt;one character at a time&lt;/strong&gt;. For each character:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Output the &lt;strong&gt;index of the character in the current list&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Move that character to the &lt;strong&gt;front of the list&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step by step:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;First character: &lt;code&gt;x&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Index in list: 23&lt;/li&gt;
&lt;li&gt;  Output: 23&lt;/li&gt;
&lt;li&gt;  Move &lt;code&gt;x&lt;/code&gt; to front → list now: &lt;code&gt;x a b c d e f g h i j k l m n o p q r s t u v w y z ...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next: &lt;code&gt;y&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Index: 24&lt;/li&gt;
&lt;li&gt;  Output: 24&lt;/li&gt;
&lt;li&gt;  Move &lt;code&gt;y&lt;/code&gt; to front → list now: &lt;code&gt;y x a b c d e f g h i j k l m n o p q r s t u v w z ...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next: &lt;code&gt;z&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Index: 25&lt;/li&gt;
&lt;li&gt;  Output: 25&lt;/li&gt;
&lt;li&gt;  Move &lt;code&gt;z&lt;/code&gt; to front → list now: &lt;code&gt;z y x a b c d e f g h i j k l m n o p q r s t u v w ...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next: space&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Index: 26 (in the updated list)&lt;/li&gt;
&lt;li&gt;  Output: 26&lt;/li&gt;
&lt;li&gt;  Move space to front&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Now the &lt;strong&gt;second &lt;code&gt;y&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;y&lt;/code&gt; → index 1 (because &lt;code&gt;y&lt;/code&gt; is now at position 1 in the list)&lt;/li&gt;
&lt;li&gt;  Output: 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Third &lt;code&gt;y&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;y&lt;/code&gt; → index 0 (because &lt;code&gt;y&lt;/code&gt; just moved to the front!)&lt;/li&gt;
&lt;li&gt;  Output: 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the encoding for &lt;code&gt;"xyz yy"&lt;/code&gt; becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;23 24 25 26 1 0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Notice how the last two &lt;code&gt;y&lt;/code&gt;'s become &lt;code&gt;1 0&lt;/code&gt;&lt;/strong&gt; — much smaller numbers than the original 24! This is the power of MTF when similar characters appear close together.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Missing Piece: Burrows-Wheeler Transform (BWT)
&lt;/h2&gt;

&lt;p&gt;But there's a problem: MTF only works well if similar patterns are already close together in the input.&lt;/p&gt;

&lt;p&gt;So now we need an algorithm that puts the same patterns close together so that we can take advantage of MTF. In fact, we need a &lt;strong&gt;rule&lt;/strong&gt; — a specific order to group characters — so that we can reverse it and get the original input.&lt;/p&gt;

&lt;p&gt;This is where the &lt;strong&gt;Burrows-Wheeler Transform (BWT)&lt;/strong&gt; comes in. It's a reversible transformation that rearranges the input text to group similar characters together, making it perfect for feeding into MTF.&lt;/p&gt;

&lt;h2&gt;
  
  
  How BWT Works
&lt;/h2&gt;

&lt;p&gt;Let's use &lt;code&gt;"banana"&lt;/code&gt; as an example. We add &lt;code&gt;$&lt;/code&gt; to mark the end: &lt;code&gt;banana$&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create all rotations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rotate one character back and repeat for all characters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;banana$
anana$b
nana$ba
ana$ban
na$bana
a$banan
$banana

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Sort lexicographically&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$banana
a$banan
ana$ban
anana$b
banana$
na$bana
nana$ba

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Take the last column&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The output is: &lt;code&gt;annb$aa&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why BWT is Powerful for English Text
&lt;/h2&gt;

&lt;p&gt;Here's where BWT really shines. Look at what happens when we have text with repeated patterns:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before sorting:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;... the dog ...
... the cat ...
... the duck ...
... the man ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After sorting lexicographically:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;he cat ... t
he dog ... t
he duck ... t
he man ... t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice something amazing? After sorting, all the rotations that start with "he" (from "the") group together!&lt;/p&gt;

&lt;p&gt;And look at the &lt;strong&gt;last column&lt;/strong&gt; — all the &lt;code&gt;t&lt;/code&gt;'s are grouped together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t
t
t
t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Reverse BWT (Decoding)
&lt;/h2&gt;

&lt;p&gt;Now the clever part: how do we get back the original string? Let's use &lt;code&gt;"cat"&lt;/code&gt; as an example.&lt;/p&gt;

&lt;p&gt;After BWT encoding &lt;code&gt;cat$&lt;/code&gt;, we get the output: &lt;code&gt;tc$a&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Observation 1: Last column + sorting = First column
&lt;/h3&gt;

&lt;p&gt;We have the &lt;strong&gt;last column&lt;/strong&gt; (the encoded output): &lt;code&gt;tc$a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we &lt;strong&gt;sort&lt;/strong&gt; it, we get the &lt;strong&gt;first column&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Last column (encoded): t c $ a
First column (sorted): $ a c t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now we have:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Row&lt;/th&gt;
&lt;th&gt;First&lt;/th&gt;
&lt;th&gt;...&lt;/th&gt;
&lt;th&gt;Last&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;t&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;a&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;c&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;c&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;t&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;a&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Observation 2: Last and First are consecutive in the original
&lt;/h3&gt;

&lt;p&gt;Since each row is a rotation, the &lt;strong&gt;last character&lt;/strong&gt; and &lt;strong&gt;first character&lt;/strong&gt; in each row are &lt;strong&gt;consecutive&lt;/strong&gt; in the original input.&lt;/p&gt;

&lt;p&gt;For example, from the row &lt;code&gt;at$c&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Last: &lt;code&gt;c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  First: &lt;code&gt;a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  This tells us: &lt;code&gt;c&lt;/code&gt; comes before &lt;code&gt;a&lt;/code&gt; → &lt;code&gt;...ca...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Observation 3: We can start with &lt;code&gt;$&lt;/code&gt; because we know where the string ends
&lt;/h3&gt;

&lt;p&gt;The complete decoding process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Start with the row that has &lt;code&gt;$&lt;/code&gt; in the last column&lt;/strong&gt; (row 2)

&lt;ul&gt;
&lt;li&gt;  First character: &lt;code&gt;c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Add &lt;code&gt;c&lt;/code&gt; to decoded string → &lt;code&gt;c&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Move to the row with &lt;code&gt;c&lt;/code&gt; in the last column&lt;/strong&gt; (row 1)

&lt;ul&gt;
&lt;li&gt;  First character: &lt;code&gt;a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Add &lt;code&gt;a&lt;/code&gt; to decoded string → &lt;code&gt;ca&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Move to the row with &lt;code&gt;a&lt;/code&gt; in the last column&lt;/strong&gt; (row 3)

&lt;ul&gt;
&lt;li&gt;  First character: &lt;code&gt;t&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Add &lt;code&gt;t&lt;/code&gt; to decoded string → &lt;code&gt;cat&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Move to the row with &lt;code&gt;t&lt;/code&gt; in the last column&lt;/strong&gt; (row 0)

&lt;ul&gt;
&lt;li&gt;  First character: &lt;code&gt;$&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  We've reached the end marker!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Putting It All Together: The Complete Compression Pipeline
&lt;/h2&gt;

&lt;p&gt;Now we can see how real compression algorithms work by combining BWT and MTF.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Compression Process
&lt;/h3&gt;

&lt;p&gt;Let's use &lt;code&gt;"banana"&lt;/code&gt; as our example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Apply BWT to preprocess and group similar characters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Original input: &lt;code&gt;banana$&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After BWT: &lt;code&gt;annb$aa&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Notice how the three &lt;code&gt;a&lt;/code&gt;'s are now grouped together at the end: &lt;code&gt;...aa&lt;/code&gt;, and the two &lt;code&gt;n&lt;/code&gt;'s are next to each other: &lt;code&gt;nn...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Apply Move-to-Front encoding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we encode &lt;code&gt;annb$aa&lt;/code&gt; using MTF:&lt;/p&gt;

&lt;p&gt;Starting list: &lt;code&gt;$ 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&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;a&lt;/code&gt; → index 1, output: &lt;code&gt;1&lt;/code&gt;, move to front&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;n&lt;/code&gt; → index 14, output: &lt;code&gt;14&lt;/code&gt;, move to front&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;n&lt;/code&gt; → index 0 (just moved to front!), output: &lt;code&gt;0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;b&lt;/code&gt; → index 3, output: &lt;code&gt;3&lt;/code&gt;, move to front&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;$&lt;/code&gt; → index 4, output: &lt;code&gt;4&lt;/code&gt;, move to front&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;a&lt;/code&gt; → index 1, output: &lt;code&gt;1&lt;/code&gt;, move to front&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;a&lt;/code&gt; → index 0 (just moved to front!), output: &lt;code&gt;0&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Final MTF output: &lt;code&gt;1 14 0 3 4 1 0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The magic:&lt;/strong&gt; Look at those two consecutive &lt;code&gt;n&lt;/code&gt;'s becoming &lt;code&gt;14 0&lt;/code&gt;, and the two consecutive &lt;code&gt;a&lt;/code&gt;'s at the end becoming &lt;code&gt;1 0&lt;/code&gt;! The smaller numbers compress much better.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Decompression Process
&lt;/h3&gt;

&lt;p&gt;To get back the original:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Reverse MTF:&lt;/strong&gt; &lt;code&gt;1 14 0 3 4 1 0&lt;/code&gt; → &lt;code&gt;annb$aa&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Reverse BWT:&lt;/strong&gt; &lt;code&gt;annb$aa&lt;/code&gt; → &lt;code&gt;banana$&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And we're back to the original string!&lt;/p&gt;

&lt;p&gt;This is the foundation of real-world compression algorithms like &lt;strong&gt;bzip2&lt;/strong&gt;, which uses exactly this BWT + MTF + Huffman combination to achieve excellent compression ratios on text data.&lt;/p&gt;

</description>
      <category>algorithms</category>
    </item>
  </channel>
</rss>
