/// <summary> /// Creates a new prefix tree node using a given symbol, symbol's weight, its left child node and right child node. /// </summary> /// /// <param name="symbol">The given symbol.</param> /// <param name="weight">The symbol's weight.</param> /// <param name="leftChildNode">The left child node.</param> /// <param name="rightChildNode">The right child node.</param> public PrefixTreeNode(byte symbol, long weight, PrefixTreeNode leftChildNode, PrefixTreeNode rightChildNode) { // Initialize the instance fields. this.symbol = symbol; this.weight = weight; this.leftChildNode = leftChildNode; this.rightChildNode = rightChildNode; }
/// <summary> /// Compares the current instance with another object of the same type. /// </summary> /// /// <param name="obj">An object to compare with this instance.</param> /// /// <returns> /// A 32-bit signed integer that indicates the relative order of the comparands. The return value has these meanings: /// <table> /// <tr><td>Less than zero</td><td>This instance is less than obj.</td></tr> /// <tr><td>Zero</td><td>This instance is equal to obj.</td></tr> /// <tr><td>Greater than zero</td><td>This instance is greater than obj.</td></tr> /// </table> /// </returns> /// /// <exception cref="ArgumentException"> /// Condition: <c>obj</c> is not the same type as this instance. /// </exception> public int CompareTo(object obj) { if (obj is PrefixTreeNode) { PrefixTreeNode otherPrefixTreeNode = (PrefixTreeNode)obj; return(this.weight.CompareTo(otherPrefixTreeNode.weight)); } else { throw new ArgumentException("Object is not a PrefixTreeNode"); } }
/// <summary> /// /// </summary> /// <returns></returns> public byte Trace(int bit) { // Trace through the prefix tree. traceNode = (bit == 1) ? traceNode.LeftChildNode : traceNode.RightChildNode; byte symbol; if (traceNode.IsLeaf) { symbol = traceNode.Symbol; InitializeTrace(); } else { symbol = 0; } return(symbol); }
/// <summary> /// Creates a prefix tree from a given character weights hash table. /// </summary> /// /// <param name="symbolWeights">The character weights.</param> public PrefixTree(long[] symbolWeights) { // Create the (binary) priority queue of prefix tree nodes (leaves). BinaryPriorityQueue binaryPriorityQueue = new BinaryPriorityQueue(); // Populate the (binary) priority queue of prefix tree nodes (leaves). for (int symbol = 0; symbol <= byte.MaxValue; symbol++) { if (symbolWeights[(byte)symbol] == 0) { continue; } PrefixTreeNode prefixTreeNode = new PrefixTreeNode((byte)symbol, (long)symbolWeights[(byte)symbol]); binaryPriorityQueue.Push(prefixTreeNode); } // Build the prefix tree using a binary priority queue. while (binaryPriorityQueue.Count != 1) { // The node with the smallest weight becomes the right child of its parent. PrefixTreeNode rightChildNode = (PrefixTreeNode)binaryPriorityQueue.Pop(); // The node with the second smallest weight becomes the left child of its parent. PrefixTreeNode leftChildNode = (PrefixTreeNode)binaryPriorityQueue.Pop(); // Create the parent node and enqueue it. PrefixTreeNode parentNode = new PrefixTreeNode(leftChildNode, rightChildNode); binaryPriorityQueue.Push(parentNode); } // The last remaning node becomes the root node of the prefix tree. rootNode = (PrefixTreeNode)binaryPriorityQueue.Pop(); // Recursively assign prefixes to the nodes strating from the root node. AssignPrefixes(); }
/// <summary> /// /// </summary> public void InitializeTrace() { traceNode = rootNode; }
/// <summary> /// Creates a new prefix tree node using its left child node and right child node. /// </summary> /// /// <param name="leftChildNode">The left child node.</param> /// <param name="rightChildNode">The right child node.</param> internal PrefixTreeNode(PrefixTreeNode leftChildNode, PrefixTreeNode rightChildNode) : this((byte)0, leftChildNode.Weight + rightChildNode.Weight, leftChildNode, rightChildNode) { }