public void combineTrees(RootedBinaryTree <T> leftTree, RootedBinaryTree <T> rightTree) { root.leftChild = leftTree.root; root.rightChild = rightTree.root; leftTree.root.parent = root; rightTree.root.parent = root; root.parent = null; leftTree.currentPosition = root; rightTree.currentPosition = root; }
} //end decompress() private static void huffman(Word[] theWords) { List <RootedBinaryTree <Word> > treeArray = new List <RootedBinaryTree <Word> >(); //make our initial list of binary trees for (int i = 0; i < theWords.Length; i++) { treeArray.Add(new RootedBinaryTree <Word>(theWords[i])); } //combine trees while (treeArray.Count > 1) { Word newWord = new Word(); newWord.plainWord = null; newWord.codeWord = null; //combine the probabilities newWord.probability = treeArray.ElementAt(0).getData().probability + treeArray.ElementAt(1).getData().probability; //make a new tree for the combined trees. RootedBinaryTree <Word> combinedTrees = new RootedBinaryTree <Word>(newWord); combinedTrees.combineTrees(treeArray.ElementAt(0), treeArray.ElementAt(1)); //make sure we are at root combinedTrees.toRoot(); int newTreeIndex = 0; //insert tree while ((combinedTrees.getData().probability >= treeArray.ElementAt(newTreeIndex).getData().probability)) { //did we reach the end? if (newTreeIndex == treeArray.Count - 1) { newTreeIndex++; break; } //if not, keep looping until we find our insert point newTreeIndex++; } //insert tree treeArray.Insert(newTreeIndex, combinedTrees); treeArray.RemoveAt(0); treeArray.RemoveAt(0); } //end while( >1) treeArray.ElementAt(0).toRoot(); RootedBinaryTree <Word> combinedTree = treeArray.ElementAt(0); string codeString = ""; assignCodes(ref codeString, theWords, combinedTree); } //end huffman()
} //end huffman() private static void assignCodes(ref string codeString, Word[] theWords, RootedBinaryTree <Word> combinedTree) { //if we can go left... if (combinedTree.moveLeft()) { //adjust codeword string accordingly... codeString += '0'; if (combinedTree.getData().plainWord != null) { //if we have a character here.... for (int i = 0; i < theWords.Length; i++) { //find the character in our 'theWords' array... if (combinedTree.getData().plainWord == theWords[i].plainWord) { //label this character with a codeword string theWords[i].codeWord = codeString; break; } } } //recusive call assignCodes(ref codeString, theWords, combinedTree); //back from recursion, remove a character from our codeword string codeString = codeString.Remove(codeString.Length - 1); } //end if(combinedTree.moveLeft()) //do the same for right sides.... if (combinedTree.moveRight()) { codeString += '1'; if (combinedTree.getData().plainWord != null) { for (int i = 0; i < theWords.Length; i++) { if (combinedTree.getData().plainWord == theWords[i].plainWord) { theWords[i].codeWord = codeString; break; } } } assignCodes(ref codeString, theWords, combinedTree); codeString = codeString.Remove(codeString.Length - 1); } //explored all possibilities, move back up.... combinedTree.moveUp(); }