private static LinkedNode BuildList(byte[] primeData) { LinkedNode root; root = new LinkedNode(256, 1); root = root.Insert(new LinkedNode(257, 1)); for (var i = 0; i < primeData.Length; i++) { if (primeData[i] != 0) { root = root.Insert(new LinkedNode(i, primeData[i])); } } return(root); }
private static LinkedNode Decode(BitStream input, LinkedNode head) { var node = head; while (node.Child0 != null) { var bit = input.ReadBits(1); if (bit == -1) { throw new Exception("Unexpected end of file"); } node = bit == 0 ? node.Child0 : node.Child1; } return(node); }
private static LinkedNode BuildTree(LinkedNode tail) { var current = tail; while (current != null) { var child0 = current; var child1 = current.Prev; if (child1 == null) { break; } var parent = new LinkedNode(0, child0.Weight + child1.Weight); parent.Child0 = child0; child0.Parent = parent; child1.Parent = parent; current.Insert(parent); current = current.Prev.Prev; } return(current); }
// This increases the weight of the new node and its antecendants // and adjusts the tree if needed private static void AdjustTree(LinkedNode newNode) { var current = newNode; while (current != null) { current.Weight++; LinkedNode insertpoint; LinkedNode prev; // Go backwards thru the list looking for the insertion point insertpoint = current; while (true) { prev = insertpoint.Prev; if (prev == null) { break; } if (prev.Weight >= current.Weight) { break; } insertpoint = prev; } // No insertion point found if (insertpoint == current) { current = current.Parent; continue; } // The following code basicly swaps insertpoint with current // remove insert point if (insertpoint.Prev != null) { insertpoint.Prev.Next = insertpoint.Next; } insertpoint.Next.Prev = insertpoint.Prev; // Insert insertpoint after current insertpoint.Next = current.Next; insertpoint.Prev = current; if (current.Next != null) { current.Next.Prev = insertpoint; } current.Next = insertpoint; // remove current current.Prev.Next = current.Next; current.Next.Prev = current.Prev; // insert current after prev var temp = prev.Next; current.Next = temp; current.Prev = prev; temp.Prev = current; prev.Next = current; // Set up parent/child links var currentparent = current.Parent; var insertparent = insertpoint.Parent; if (currentparent.Child0 == current) { currentparent.Child0 = insertpoint; } if (currentparent != insertparent && insertparent.Child0 == insertpoint) { insertparent.Child0 = current; } current.Parent = insertparent; insertpoint.Parent = currentparent; current = current.Parent; } }