using
System;
using
System.Collections.Generic;
using
System.Linq;
namespace
HuffmanEncoding
{
class
FrequencyTable
{
private
readonly
Dictionary<
char
,
int
> _freq =
new
Dictionary<
char
,
int
>();
public
void
Add(
char
c)
{
if
(_freq.ContainsKey(c))
{
_freq++;
}
else
{
_freq = 1;
}
}
public
Dictionary<
char
,
int
> ToDictionary()
{
return
_freq;
}
}
class
HuffmanNode : IComparable<HuffmanNode>
{
public
HuffmanNode Left {
get
;
set
; }
public
HuffmanNode Right {
get
;
set
; }
public
char
Data {
get
;
set
; }
public
int
Frequency {
get
;
set
; }
public
HuffmanNode(
char
data,
int
freq)
{
Data = data;
Frequency = freq;
}
public
int
CompareTo(HuffmanNode other)
{
return
Frequency - other.Frequency;
}
}
class
HuffmanEncoder
{
private
readonly
Dictionary<
char
,
string
> _codes =
new
Dictionary<
char
,
string
>();
private
readonly
List<HuffmanNode> _minHeap =
new
List<HuffmanNode>();
private
void
BuildHuffmanTree(Dictionary<
char
,
int
> freq)
{
foreach
(
var
kvp
in
freq)
{
_minHeap.Add(
new
HuffmanNode(kvp.Key, kvp.Value));
}
_minHeap.Sort();
while
(_minHeap.Count > 1)
{
var
left = _minHeap.First();
_minHeap.RemoveAt(0);
var
right = _minHeap.First();
_minHeap.RemoveAt(0);
var
top =
new
HuffmanNode(
'$'
, left.Frequency + right.Frequency);
top.Left = left;
top.Right = right;
_minHeap.Add(top);
_minHeap.Sort();
}
}
private
void
StoreCodes(HuffmanNode root,
string
str)
{
if
(root ==
null
)
{
return
;
}
if
(root.Data !=
'$'
)
{
_codes[root.Data] = str;
}
StoreCodes(root.Left, str +
"0"
);
StoreCodes(root.Right, str +
"1"
);
}
public
void
PrintCodes(HuffmanNode root,
string
str)
{
if
(root ==
null
)
{
return
;
}
if
(root.Data !=
'$'
)
{
Console.WriteLine(root.Data +
" : "
+ str);
}
PrintCodes(root.Left, str +
"0"
);
PrintCodes(root.Right, str +
"1"
);
}
public
string
DecodeFile(HuffmanNode root,
string
s)
{
string
ans =
""
;
HuffmanNode curr = root;
int
n = s.Length;
for
(
int
i = 0; i < n; i++)
{
if
(s[i] ==
'0'
)
{
curr = curr.Left;
}
else
{
curr = curr.Right;
}
if
(curr.Left ==
null
&& curr.Right ==
null
)
{
ans += curr.Data;
curr = root;
}
}
return
ans +
"\0"
;
}
public
void
BuildCodes(Dictionary<
char
,
int
> freq)
{
BuildHuffmanTree(freq);
StoreCodes(_minHeap.First(),
""
);
}
public
Dictionary<
char
,
string
> GetCodes()
{
return
_codes;
}
public
HuffmanNode GetRoot()
{
return
_minHeap.First();
}
}
class
Program
{
static
void
Main(
string
[] args)
{
string
str =
"geeksforgeeks"
;
string
encodedString =
""
;
string
decodedString;
var
freqTable =
new
FrequencyTable();
foreach
(
char
c
in
str)
{
freqTable.Add(c);
}
var
huffmanEncoder =
new
HuffmanEncoder();
huffmanEncoder.BuildCodes(freqTable.ToDictionary());
Console.WriteLine(
"Character With their Frequencies:"
);
foreach
(
var
kvp
in
huffmanEncoder.GetCodes())
{
Console.WriteLine($
"{kvp.Key} : {kvp.Value}"
);
}
foreach
(
char
c
in
str)
{
encodedString += huffmanEncoder.GetCodes();
}
Console.WriteLine(
"\nEncoded Huffman data:"
);
Console.WriteLine(encodedString);
decodedString = huffmanEncoder.DecodeFile(huffmanEncoder.GetRoot(), encodedString);
Console.WriteLine(
"\nDecoded Huffman Data:"
);
Console.WriteLine(decodedString);
}
}
}