function dict = huffmandict(symbols, p)
% HUFFMANDICT Generate Huffman dictionary.
%
% dict = HUFFMANDICT(symbols, p) generates a Huffman code dictionary
% based on the input symbol probabilities p. symbols is a vector of
% distinct data source symbols. The function returns a cell array
% containing a two-column lookup table. Column 1 contains the input
% symbols and column 2 contains their corresponding Huffman codes.
nSymbols = length(p);
dict = cell(nSymbols, 2);
if nSymbols == 1
dict{1, 1} = symbols;
dict{1, 2} = '';
else
% Construct initial binary tree nodes
counts = zeros(2*nSymbols-1, 1); % Node counts
counts(1:nSymbols) = p; % Assign leaf node counts
leftChild = zeros(2*nSymbols-1, 1); % Left children
rightChild = zeros(2*nSymbols-1, 1); % Right children
parent = zeros(2*nSymbols-1, 1); % Parent nodes
for i = (nSymbols+1):(2*nSymbols-1)
[counts, index] = sort(counts);
leftChild(i) = index(1);
rightChild(i) = index(2);
parent(index(1)) = i;
parent(index(2)) = i;
counts(i) = counts(1) + counts(2);
end
% Encode each symbol using its corresponding path in the binary tree
codeWord = repmat(' ', nSymbols, nSymbols);
for i = 1:nSymbols
node = i;
while parent(node) ~= 0
if leftChild(parent(node)) == node
codeWord(i, nSymbols - ceil(log2(nSymbols) - log2(node+1))) = '0';
else
codeWord(i, nSymbols - ceil(log2(nSymbols) - log2(node+1))) = '1';
end
node = parent(node);
end
dict{i, 1} = symbols(i);
dict{i, 2} = fliplr(codeWord(i, :));
end
end
function comp = huffmanenco(sig, dict)
% HUFFMANENCO Perform Huffman encoding.
%
% comp = HUFFMANENCO(sig, dict) encodes the input signal sig using the
% provided Huffman dictionary dict. The function returns a binary
% string containing the encoded message.
nBits = 0;
for i = 1:length(sig)
index = find(strcmp(dict(:, 1), sig(i)));
nBits = nBits + length(dict{index, 2});
end
comp = repmat('0', 1, nBits);
k = 1;
for i = 1:length(sig)
index = find(strcmp(dict(:, 1), sig(i)));
codeWord = dict{index, 2};
comp(k:k+length(codeWord)-1) = codeWord;
k = k + length(codeWord);
end