public HuffmanTree() { root = null; subtreeRoot = null; EncodeDict = new Dictionary<char, string>(); DecodeDict = new Dictionary<string, char>(); }
public string huffCode;//stores huffmanCode public BinTreeNode(KeyValuePair<char, int> pKvp) { kvp = pKvp; left = null; right=null; huffCode = String.Empty; }
public void GenerateHuffmanTreev2(WordFreqGenerator wordFreq) { /*Huffman (c) n = |c| Q = c for i =1 to n-1 do z = Allocate-Node () x = left[z] = EXTRACT_MIN(Q) y = right[z] = EXTRACT_MIN(Q) f[z] = f[x] + f[y] INSERT (Q, z) return EXTRACT_MIN(Q) */ int n = wordFreq.WordStatsDict.Count(); PQueue Q = new PQueue(); BinTreeNode node1; BinTreeNode node2; BinTreeNode node3; //Add each leaf to priority Q foreach(KeyValuePair<char, int> kvp in wordFreq.WordStatsDict) { node1 = new BinTreeNode(kvp); Q.Enqueue(node1); } for (int i = 1; i < n; i++) { node1 = Q.Dequeue(); node2 = Q.Dequeue(); node3 = MergeNodes(node1, node2); Q.Enqueue(node3); } root = Q.Dequeue(); }
//traverse the tree and generate code for each key public void TraverseTreeBFSAndGenCode(BinTreeNode node) { if (node == null) return; Queue<BinTreeNode> BFSQueue = new Queue<BinTreeNode>(); //special case - single node if (node.left == null && node.right == null) { node.huffCode = "1"; if (node.kvp.Key != ':') { if (!EncodeDict.ContainsKey(node.kvp.Key)) EncodeDict.Add(node.kvp.Key, node.huffCode); Console.WriteLine("Key {0} Code {1}", node.kvp.Key, node.huffCode); } return; //added later not verified } BFSQueue.Enqueue(node); BinTreeNode currentNode; while (BFSQueue.Count != 0) { try { currentNode = BFSQueue.Dequeue(); } catch (InvalidOperationException e) { Console.WriteLine("{0}", e); break; } if (currentNode.kvp.Key != ':') { if (!EncodeDict.ContainsKey(currentNode.kvp.Key)) EncodeDict.Add(currentNode.kvp.Key, currentNode.huffCode); Console.WriteLine("Key {0} Code {1}", currentNode.kvp.Key, currentNode.huffCode); } //IMP: CHECK FOR NULL BEFORE ENQUEUEING if (currentNode.left != null) { //if (currentNode.left.left == null && currentNode.left.right == null) currentNode.left.huffCode = currentNode.huffCode + "0"; BFSQueue.Enqueue(currentNode.left); } if (currentNode.right != null) { // if (currentNode.right.left == null && currentNode.right.right == null) currentNode.right.huffCode = currentNode.huffCode + "1"; BFSQueue.Enqueue(currentNode.right); } } Console.WriteLine("Entries in the Encode Dictionary are:"); foreach (KeyValuePair<char, string> kvp in EncodeDict) { Console.WriteLine("Key {0} Code {1}", kvp.Key, kvp.Value); //Populate Decode dictionary DecodeDict.Add(kvp.Value, kvp.Key); } }
public void Enqueue(BinTreeNode item) { int index = numElem; if (item == null || index >= 39) return;// first element stored at 1 while (index > 1 && item.kvp.Value < pQ[index / 2].kvp.Value) { pQ[index] = pQ[index / 2]; index = index / 2; } pQ[index] = item; numElem++; }
private BinTreeNode MergeNodes(BinTreeNode node1, BinTreeNode node2) { BinTreeNode parentNode = new BinTreeNode(new KeyValuePair<char, int>(':', node1.kvp.Value + node2.kvp.Value));//use ':' for denoting internal parent //Ensure left node has higher value if (node1.kvp.Value > node2.kvp.Value) { parentNode.left = node1; parentNode.right = node2; } else { parentNode.left = node2; parentNode.right = node1; } return parentNode; }
public BinTreeNode Dequeue() { if (pQ[1] == null || numElem <= 1) return null; BinTreeNode itemtoBeReturned = pQ[1]; BinTreeNode lastElement = pQ[--numElem]; int childIndex; int i; for(i =1; i*2<=numElem; i =childIndex) { //find smaller child - important step childIndex =i*2; if(childIndex!=numElem) if(pQ[childIndex+1].kvp.Value < pQ[childIndex].kvp.Value) childIndex++; //percolate one level if(lastElement.kvp.Value>pQ[childIndex].kvp.Value) pQ[i] = pQ[childIndex]; else break; } pQ[i] = lastElement; pQ[numElem] = null; return itemtoBeReturned; }