<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Huffman Coding :: CS3 course</title><link>https://robark.gitlab.io/huffman/index.html</link><description>Huffman Coding Lossless compression</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 28 Jun 2021 19:36:20 +0000</lastBuildDate><atom:link href="https://robark.gitlab.io/huffman/index.xml" rel="self" type="application/rss+xml"/><item><title>Example</title><link>https://robark.gitlab.io/huffman/example/index.html</link><pubDate>Wed, 23 Jun 2021 23:14:47 +0000</pubDate><guid>https://robark.gitlab.io/huffman/example/index.html</guid><description>Huffman Coding example of “mississippi river” Algorithm:
-combine last 2 nodes of linked list to create a binary tree. -root node string is concatenation of last node + second last node strings -root node sum is sum of last node + second last node integers -insert root node of new binary tree into linked list (insertion is sorted by integer then sub sorted by string if integers are equal) -repeat until only 1 node left in linked list.</description></item><item><title>Solution</title><link>https://robark.gitlab.io/huffman/solution/index.html</link><pubDate>Mon, 28 Jun 2021 19:36:20 +0000</pubDate><guid>https://robark.gitlab.io/huffman/solution/index.html</guid><description>Huffman Coding solution to generate binary tree and code for each unique char in string I fixed having duplicate functions tinsert and linsert by having map2LL function create a new node then pass the new node to linsert.
#include &lt;iostream&gt; #include &lt;map&gt; #include &lt;vector&gt; #include &lt;algorithm&gt; using namespace std; struct node{ node(string , int , node* , node* , node*); string str; int num; node* next; node* left; node* right; }; node::node(string s, int i, node* n=0, node* l=0, node* r=0){ str = s; num = i; next = n; left = l; right = r; } bool paircmp(pair &lt;string , int&gt; &amp;a, pair &lt;string, int&gt; &amp;b){ return a.second &gt; b.second; } vector &lt;pair &lt;string, int&gt; &gt; map2VecPair( map &lt; char, int&gt; cimap){ //returns sorted vector of pairs of leaf nodes in map vector &lt; pair&lt;string, int&gt; &gt; nodeVec; map&lt;char,int&gt;::iterator i; for ( i = cimap.begin(); i != cimap.end(); i++ ) { pair &lt;string, int&gt; pr; pr.first=i-&gt;first; pr.second=i-&gt;second; nodeVec.push_back(pr); } sort(nodeVec.begin(), nodeVec.end(), paircmp); return nodeVec; } void printLL(node* nd){ //print linked list if (nd == 0) return; cout&lt;&lt; nd-&gt;str &lt;&lt;":"&lt;&lt;nd-&gt;num&lt;&lt;" , "; printLL(nd-&gt;next); } int lsize(node* nd){ //return size of linked list if (nd == 0) return 0; return 1 + lsize(nd-&gt;next); } void linsert(node* &amp;p, node* &amp;root){ //insert node p into linked list (sorted) if (root == 0) { root = p; return; } else if (p-&gt;num &lt; root-&gt;num) { node* temp= root; root = p; root-&gt;next = temp; return; } else if (p-&gt;num == root-&gt;num) { if (p-&gt;str &gt; root-&gt;str) { node* temp= root; root = p; root-&gt;next = temp; return; } else { linsert(p, root-&gt;next);//equal num but str is bigger return; } } else //p-&gt;num &lt; root-&gt;num { linsert(p, root-&gt;next); return; } } void gentree(node* &amp;root){ //convert first two nodes of linked list into a new binary tree //and insert top node of new tree back into linked list (sorted) if (lsize(root) &lt; 2) { return; //safety check } string concat= root-&gt;str + (root-&gt;next)-&gt;str; int sum = root-&gt;num + (root-&gt;next)-&gt;num; node* p = new node(concat, sum); p-&gt;left = root; p-&gt;right = root-&gt;next; root = (root-&gt;next)-&gt;next; //third node is now the new root in the list linsert(p, root); } void freenode(node* n){ //free binary tree memory if (n == 0) return; freenode(n-&gt;left); freenode(n-&gt;right); delete n; } string gencode(string s, node* &amp;root){ // generate bit string of 1's and 0's that represent path down binary tree // to leaf node if (s == root-&gt;str) return (""); else if (((root-&gt;left)-&gt;str).find(s) != string::npos) //found s in left tree { return "0"+gencode(s, root-&gt;left); } else { return "1"+gencode(s, root-&gt;right); } } map &lt;char, int&gt; genUniqChars(string text){ //generate map of key:unique chars with value: associated int occurance map &lt; char, int &gt; cimap; for (unsigned int x=0; x &lt; text.size() ;x++) { if ( cimap.find(text[x]) == cimap.end() ) //not found { cimap[text[x]] = 1; } else { cimap[text[x]] = cimap[text[x]] + 1; } } return cimap; } void map2LL(node* &amp;root, map &lt;char , int&gt; cimap){ //convert map of char / int to sorted linked list map&lt;char,int&gt;::iterator i; for ( i = cimap.begin(); i != cimap.end(); i++ ) { string s(1, i-&gt;first); //alternate string ctor to fill string with n(arg1) consecutive chars(arg2) node* p= new node(s, i-&gt;second); linsert(p, root); } } int main(){ string text("mississippi river"); //getline(cin, text); //cout &lt;&lt; text &lt;&lt; endl; map &lt; char, int &gt; cimap = genUniqChars(text); node* root(0); map2LL(root, cimap); //generate binary tree while (lsize(root) &gt;1) { cout&lt;&lt;"LINKED LIST: "; printLL(root); cout&lt;&lt;endl; gentree(root); cout&lt;&lt;endl; cout&lt;&lt;"TREE: "; } printLL(root); cout&lt;&lt;endl; vector &lt;pair &lt;string, int&gt; &gt; pv = map2VecPair(cimap); for (auto it : pv) { cout &lt;&lt; it.first &lt;&lt; " " &lt;&lt; it.second &lt;&lt; " : "&lt;&lt; gencode(it.first, root)&lt;&lt;endl; } cout&lt;&lt;endl; freenode(root); return 0; }</description></item></channel></rss>