# Include "stdafx. h"
# Include <iostream>
Using std: cout;
Using std: cin;
Using std: endl;
// Store the data structure of the HuffmanTree
Typedef struct tagHuffmanTree
{
Unsigned int nWeight;
Unsigned int nParent, nLchild, nRchild; // used to save the node position in the array
} HTNode, * HuffmanTree; // dynamically allocates an array to store the Heman tree.
Typedef char * HuffmanCodeLine;
Typedef char ** HuffmanCode; // dynamically allocates an array to store the Heman encoding table .. Level 2 pointer
// Locate the two leaf nodes whose parent is 0 and whose weight is the smallest from the sequence.. nMin1 and nMin2 are the positions in the array.
Void SelectMinWeight (HuffmanTree & HT, int nNodeCount, int & nMin1, int & nMin2)
{
Int I = 0;
Int c = 0;
Int nMinWeight1 = 65535;
Int nMinWeight2 = 65535;
Int * pOrder = new int [nNodeCount];
For (I = 1; I <= nNodeCount; ++ I)
{
If (0 = HT [I]. nParent) // calculate the node and subscript where parent is 0
{
POrder [c ++] = I;
}
}
// Compare the weight of a node with parent 0 and obtain a location with a smaller weight
For (I = 0; I <c; ++ I)
{
// In each loop, the smaller value is always saved to nMinWeight1, and the smaller value is saved to nMinWeight2;
// After execution, nMinWeight1 is the minimum value and nMinWeight2 is the secondary small value.
Int nTempWeight = HT [pOrder [I]. nWeight;
If (nTempWeight <nMinWeight1)
{
NMinWeight2 = nMinWeight1;
NMin2 = nMin1;
NMinWeight1 = nTempWeight;
NMin1 = pOrder [I];
}
Else if (nTempWeight <nMinWeight2)
{
NMinWeight2 = nTempWeight;
NMin2 = pOrder [I];
}
}
If (pOrder)
{
Delete [] pOrder;
POrder = NULL;
}
Return;
}
// Build and obtain the leaf Node Code
Void HuffmanCoding (HuffmanTree & HT, HuffmanCode & HC, int * pWeight, int nLeafCount)
{
If (nLeafCount <= 1)
{
Return;
}
// PWeight is the array of stored weights; nLeafCount is the number of leaf nodes, that is, the number of nodes to be encoded.
Int nNodeCount = 2 * nLeafCount-1; // total number of nodes
HT = new HTNode [nNodeCount + 1]; // apply for one more space, which is not used for unit 0
HTNode * pTemp = NULL;
Int I = 0;
// Initialize the first several storage units to store leaf nodes.
For (I = 1, pTemp = HT + 1; I <= nLeafCount; ++ I, ++ pTemp, ++ pWeight) // pTemp = HT + 1, unit 0th is not required
{
(* PTemp). nWeight = * pWeight;
(* PTemp). nParent = 0;
(* PTemp). nLchild = 0;
(* PTemp). nRchild = 0;
}
// Several storage units after HT initialization, all of which store,
For (; I <= nNodeCount; ++ I, ++ pTemp)
{
(* PTemp). nWeight = 0;
(* PTemp). nParent = 0;
(* PTemp). nLchild = 0;
(* PTemp). nRchild = 0;
}
// Create a HuffmanTree.
Int nMin1, nMin2;
For (I = nLeafCount + 1; I <= nNodeCount; ++ I)
{
// In HT [1... I-1], find the parent is 0 and the smallest two values. NMin1 and nMin2 respectively (nMin1 and nMin2 are in the array)
SelectMinWeight (HT, I-1, nMin1, nMin2 );
HT [nMin1]. nParent = I;
HT [nMin2]. nParent = I;
HT [I]. nLchild = nMin1;
HT [I]. nRchild = nMin2;
HT [I]. nWeight = HT [nMin1]. nWeight + HT [nMin2]. nWeight;
}
// ---------------- Encoding part -------------------------------
// Reverse encoding from leaves to roots
HC = new HuffmanCodeLine [nLeafCount + 1]; // unit 0 is not used
Char * pCode = new char [nLeafCount]; // used to save the encoding sequence of a node
Memset (pCode, 0, nLeafCount );
// PCode [nLeafCount-1] = '\ 0'; // encoding Terminator
Int nStart = 0;
For (I = 1; I <= nLeafCount; ++ I) // traverse leaf nodes
{
NStart = nLeafCount-1; // the location of the encoding Terminator, the last location of the pCode Array
Int nTempPos;
Unsigned int nParent;
For (nTempPos = I, nParent = HT [I]. nParent; nParent! = 0; nTempPos = nParent, nParent = HT [nParent]. nParent)
{
If (nTempPos = HT [nParent]. nLchild) // The left subtree is assigned 0 by default, and the right subtree is assigned 1
{
PCode [-- nStart] = '0 ';
}
Else
{
PCode [-- nStart] = '1 ';
}
}
HC [I] = new char [nLeafCount-nStart];
Strcpy (HC [I], & pCode [nStart]); // copy the encoding of a leaf node
}
If (pCode)
{
Delete [] pCode;
PCode = NULL;
}
Return;
}
// Main program entry
Int _ tmain (int argc, _ TCHAR * argv [])
{
Int I = 0;
Int nLeafCount = 0; // The number of leaves is the number of nodes to be encoded.
// Int nNodeCount = 0;
Cout <"Input num of leaf:" <endl;
Cin> nLeafCount;
While (0 = nLeafCount)
{
Cout <"Num of leaf can not be 0" <endl;
Cin> nLeafCount;
}
// Apply for memory to save the character value and weight
Char * pLetter = new char [nLeafCount]; // Save the character value
Int * pWeight = new int [nLeafCount]; // Save the weight
For (I = 0; I <nLeafCount; ++ I)
{
Cout <"Input letter and weight" <endl;
Cin> pLetter [I]> pWeight [I];
}
HuffmanTree HT = NULL;
HuffmanCode HC = NULL;
HuffmanCoding (HT, HC, pWeight, nLeafCount); // call the method to create a Huffman tree and obtain the encoding sequence
For (int I = 1; I <= nLeafCount; ++ I) // code of the output leaf node
{
Cout <HC [I] <endl;
}
System ("pause ");
If (HT) // releases tree resources
{
Delete [] HT;
HT = NULL;
}
For (int I = 1; I <= nLeafCount; ++ I) // release the encoded resource.
{
Delete [] HC [I];
HC [I] = NULL;
}
If (HC)
{
Delete [] HC;
HC = NULL;
}
If (pLetter)
{
Delete [] pLetter;
PLetter = NULL;
}
If (pWeight)
{
Delete [] pWeight;
PWeight = NULL;
}
Return 0;
}