Symbol code file
Submitted by Daryle on Thu, 05/17/2012 - 15:41
Filename: | symbol.cpp |
Project Name: | Huffman Encoding Trees |
Language: | C++ |
Description: | |
Code:
//======================================================== // CHARACTER METHODS //======================================================== Symbol::Symbol() { Parent = NULL; LeftChild = NULL; RightChild = NULL; Probability=0; Character='\0'; Mark = false; CodeBit[0] = '\0'; Depth = 1; } //========================================== Symbol::Symbol(char InputChar, float InputProb) { Parent = NULL; LeftChild = NULL; RightChild = NULL; Mark = false; CodeBit[0] = '\0'; Depth = 1; Character = InputChar; Probability = InputProb; } //========================================== Symbol::~Symbol() {;} //======================================================== // TREE METHODS //======================================================== Tree::Tree() { Root = NULL; Count=0; PtrCurrent=Root; Depth=0; BranchCounter=0; } //========================================== Tree::~Tree() { //Delete all Character objects before //Destruction } //======================================================== //INSERTSYMBOL IS USED BY THE LIST TREE TO CONSTRUCT //A LINKED LIST OF SYMBOLS. FOR THIS PURPOSE, IT USES //THE LEFTCHILD POINTERS TO POINT TO THE NEXT ENTRY AND //PARENT POINTERS TO POINT TO THE LAST ENTRY void Tree::insertSymbol(char MyCharacter, float MyProb){ Symbol *Ptr = new Symbol(MyCharacter,MyProb); assert (Ptr !=NULL); Ptr->LeftChild = Root; Root->Parent = Ptr; Root = Ptr; Count++; //Watch for special case of an empty tree if (Root == NULL) { Root = PtrCurrent = Ptr; return; } return; } //========================================== //THIS OVERLOADED METHOD IS USED TO INSERT A SYMBOL //OBJECT INTO THE HUFFMAN TREE void Tree::insertSymbol(Symbol *Symbol1, Symbol *Symbol2) { Symbol *Nanny = new Symbol(); Nanny->LeftChild = Symbol1; Nanny->RightChild = Symbol2; Symbol1->Parent = Symbol2->Parent = Nanny; Nanny->Probability = Symbol1->Probability + Symbol2->Probability; BranchCounter++; if (BranchCounter==1) Root=Nanny; if (BranchCounter>=2) { Symbol *NewRoot=new Symbol(); NewRoot->LeftChild=Root; NewRoot->RightChild=Nanny; Nanny->Parent = Root->Parent = NewRoot; NewRoot->Probability = Root->Probability + Nanny->Probability; Root=NewRoot; } } //========================================== //THIS OVERLOADED METHOD IS USED TO INSERT A SYMBOL //OBJECT INTO THE HUFFMAN TREE void Tree::insertSymbol(Symbol *Symbol1) { Symbol *NewRoot = new Symbol; NewRoot->LeftChild = Root; NewRoot->RightChild = Symbol1; Root->Parent = Symbol1->Parent = NewRoot; NewRoot->Probability = Symbol1->Probability + Root->Probability; BranchCounter++; Root=NewRoot; } //========================================== int Tree::showLength(void){ return Count; } //========================================== void Tree::displayTree() { for (Symbol *Ptr=Root; Ptr; Ptr=Ptr->LeftChild) cout << Ptr->Character << " " << Ptr->Probability << " "; cout << endl; } //========================================== //FINDLOW FINDS THE LOWEST UNMARKED SYMBOL IN THE LIST. //IF ALL SYMBOLS ARE USED UP (I.E. MARKED), IT RETURNS //-1. OTHERWISE IT RETURNS 0 int Tree::findLow() { Symbol *Ptr = Root; bool FoundFlag = false; float LowValue = 1; while (Ptr != NULL) { if ((Ptr->Probability<=LowValue) && (Ptr->Mark==false)) { FoundFlag = true; PtrCurrent=Ptr; LowValue = Ptr->Probability; } Ptr=Ptr->LeftChild; } if (FoundFlag == true) return 0; else return -1; } //========================================== int Tree::markSymbol(){ if (PtrCurrent == NULL) return -1; else { PtrCurrent->Mark = true; return 0; } } //========================================== Symbol* Tree::removeSymbol(){ Symbol *Tmp; if (Root == NULL) //Is the list empty? return 0; if ((PtrCurrent->Mark != true) || (PtrCurrent == NULL)) return 0; //EXTRICATE SYMBOL FROM LIST TREE Tmp = PtrCurrent; if (PtrCurrent != Root) PtrCurrent->LeftChild->Parent = PtrCurrent->Parent; else { PtrCurrent->LeftChild->Parent=NULL; Root=PtrCurrent->LeftChild; } PtrCurrent->Parent->LeftChild = PtrCurrent->LeftChild; PtrCurrent->Parent=PtrCurrent->LeftChild = NULL; PtrCurrent = NULL; return Tmp; } //========================================== void Tree::moveSymbols(Tree *HuffmanTree){ Symbol *Symbol1=NULL, *Symbol2=NULL; int Length=this->showLength(); while (Length > 1) { if (findLow()) { Symbol1=NULL; cerr << "Error: Lowest value not found" << endl; } else { markSymbol(); Symbol1=removeSymbol(); Length--; } if (findLow()){ Symbol2=NULL; cerr << "Error: Lowest value not found" << endl; } else{ markSymbol(); Symbol2=removeSymbol(); Length--; } HuffmanTree->insertSymbol(Symbol1,Symbol2); } if (Length == 1) { if (!findLow()) cerr << "Error: Last element not found!" << endl; markSymbol(); Symbol1=removeSymbol(); Length--; HuffmanTree->insertSymbol(Symbol1); } return; } //========================================== void Tree::printTree(){ Symbol *Current=Root; if (Root != NULL) { //Print Header cout << "Char Probability Code Location Neighbours" \ << endl; printTree(Root->LeftChild); printTree(Root->RightChild); cout << hex; cout <<setiosflags(ios::fixed | ios::showpoint | ios::internal); cout << setiosflags(ios::unitbuf | ios::right); cout << "\""<< setw(1) << Current->Character<<"\""; if (Current->Character=='\0') cout << " "; cout << setiosflags(ios::left); cout << setw(12) << setprecision(7) << Current->Probability << " "; cout << setw(17) << setfill(' ') << Current->CodeBit; cout << " " << hex << Current; cout << " " << hex << Current->Parent << " " << Current->LeftChild; cout << " " << Current->RightChild << dec << endl; } return; } //========================================== void Tree::printTree(Symbol *Current){ if (Current != NULL) { printTree(Current->LeftChild); printTree(Current->RightChild); cout << hex; cout <<setiosflags(ios::fixed | ios::showpoint | ios::internal); cout << setiosflags(ios::unitbuf | ios::right); cout << "\""<< setw(1) << Current->Character<<"\""; if (Current->Character=='\0') cout << " "; cout << setiosflags(ios::left); cout << setw(12) << setprecision(7) << Current->Probability << " "; cout << setw(17) << setfill(' ') << Current->CodeBit; cout << " " << hex << Current; cout << " " << hex << Current->Parent << " " << Current->LeftChild; cout << " " << Current->RightChild << dec << endl; } return; } //========================================== void Tree::assignBits(){ if (Root != NULL) { assignBits(Root->LeftChild,"0"); assignBits(Root->RightChild,"1"); } return; } //========================================== void Tree::assignBits(Symbol *Current, char *BitSet){ char BitBuffer[16]; BitBuffer[0]='\0'; strcat(BitBuffer,BitSet); if (Current != NULL) { strcpy(Current->CodeBit,BitSet); assignBits(Current->LeftChild,strcat(BitBuffer,"0")); BitBuffer[0]='\0'; strcat(BitBuffer,BitSet); assignBits(Current->RightChild,strcat(BitBuffer,"1")); } return; } //========================================== void Tree::writeTable(ofstream *OUTPUT){ Symbol *Current=Root; if (Root !=NULL) { if (Current->Character!='\0'){ *OUTPUT << Current->Character << " " << Current->CodeBit << endl; } writeTable(OUTPUT,Current->LeftChild); writeTable(OUTPUT,Current->RightChild); } } //========================================== void Tree::writeTable(ofstream *OUTPUT,Symbol* Current){ if (Current !=NULL) { if (Current->Character!='\0') *OUTPUT << Current->Character << " " << Current->CodeBit << endl; this->writeTable(OUTPUT,Current->LeftChild); this->writeTable(OUTPUT,Current->RightChild); } }