hi there
I'm implementing the halfman algorithm that used for compressing the data in c# now i'm going to draw it's tree (the tree that made by encode method). the tree is a binary kind as you see in this link http://en.wikipedia.org/wiki/File:Huffman_tree_2.svg)
im going to draw my tree exactly like what's you seen in above link
i want to know is c# has any tools or method that could help me to do these easier.
my code is here:
public class Node
{
public char Symbol { get; set; }
public int Frequency { get; set; }
public Node Right { get; set; }
public Node Left { get; set; }
public List<bool> Traverse(char symbol, List<bool> data)
{
if (Right == null && Left == null)
{
if (symbol.Equals(this.Symbol))
{
return data;
}
else
{
return null;
}
}
else
{
List<bool> left = null;
List<bool> right = null;
if (Left != null)
{
List<bool> leftPath = new List<bool>();
leftPath.AddRange(data);
leftPath.Add(false);
left = Left.Traverse(symbol, leftPath);
}
if (Right != null)
{
List<bool> rightPath = new List<bool>();
rightPath.AddRange(data);
rightPath.Add(true);
right = Right.Traverse(symbol, rightPath);
}
if (left != null)
{
return left;
}
else
{
return right;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace HuffmanTest
{
public class HuffmanTree
{
private List<Node> nodes = new List<Node>();
public Node Root { get; set; }
public Dictionary<char, int> Frequencies = new Dictionary<char, int>();
public void Build(string source)
{
for (int i = 0; i < source.Length; i++)
{
if (!Frequencies.ContainsKey(source[i]))
{
Frequencies.Add(source[i], 0);
}
Frequencies[source[i]]++;
}
foreach (KeyValuePair<char, int> symbol in Frequencies)
{
nodes.Add(new Node() { Symbol = symbol.Key, Frequency = symbol.Value });
}
while (nodes.Count > 1)
{
List<Node> orderedNodes = nodes.OrderBy(node => node.Frequency).ToList<Node>();
if (orderedNodes.Count >= 2)
{
List<Node> taken = orderedNodes.Take(2).ToList<Node>();
Node parent = new Node()
{
Symbol = '*',
Frequency = taken[0].Frequency + taken[1].Frequency,
Left = taken[0],
Right = taken[1]
};
nodes.Remove(taken[0]);
nodes.Remove(taken[1]);
nodes.Add(parent);
}
this.Root = nodes.FirstOrDefault();
}
}
public BitArray Encode(string source)
{
List<bool> encodedSource = new List<bool>();
for (int i = 0; i < source.Length; i++)
{
List<bool> encodedSymbol = this.Root.Traverse(source[i], new List<bool>());
encodedSource.AddRange(encodedSymbol);
}
BitArray bits = new BitArray(encodedSource.ToArray());
return bits;
}
public string Decode(BitArray bits)
{
Node current = this.Root;
string decoded = "";
foreach (bool bit in bits)
{
if (bit)
{
if (current.Right != null)
{
current = current.Right;
}
}
else
{
if (current.Left != null)
{
current = current.Left;
}
}
if (IsLeaf(current))
{
decoded += current.Symbol;
current = this.Root;
}
}
return decoded;
}
public bool IsLeaf(Node node)
{
return (node.Left == null && node.Right == null);
}
}
and my main code is here:
and this is my main code:
class Program
{
static void Main(string[] args)
{
string input = "Hussein";
HuffmanTree huffmanTree = new HuffmanTree();
huffmanTree.Build(input);
BitArray encoded = huffmanTree.Encode(input);
Console.Write("Encoded: ");
foreach (bool bit in encoded)
{
Console.Write((bit ? 1 : 0) + "");
}
Console.WriteLine();
string decoded = huffmanTree.Decode(encoded);
Console.WriteLine("Decoded: " + decoded);
Console.ReadLine();
}
}
As you see here we could use this part of code to draw our tree but i dont know how:
public string Decode(BitArray bits)
{
Node current = this.Root;
string decoded = "";
foreach (bool bit in bits)
{
if (bit)
{
if (current.Right != null)
{
current = current.Right;
}
}
else
{
if (current.Left != null)
{
current = current.Left;
}
}
if (IsLeaf(current))
{
decoded += current.Symbol;
current = this.Root;
}
}
return decoded;
}
i wrote these but it is not enough and really difficult
what can i do
private void Print_Root()
{
Graphics g = this.CreateGraphics();
g.DrawEllipse(Pens.Black, this.Width / 2, 0, 20, 20);
}
private void print_Right(int left,int top)
{
Graphics g = this.CreateGraphics();
g.DrawEllipse(Pens.Black, left, top, 20, 20);
g.DrawLine(Pens.Black, left+3, top+3, left-10, top-10);
}
private void print_left(int left, int top)
{
Graphics g = this.CreateGraphics();
g.DrawEllipse(Pens.Black, left, top, 20, 20);
g.DrawLine(Pens.Black, left + 3, top + 3, left - 10, top - 10);
}
i dont have much time
Would you please to help me to draw
and it is useful to use MSAGL component(i don't know it is component or .dll)
it is free or we have to buy it.
thanks
Edit: Removed C++ tag - some of the code may be C++/CLI (I'd have no idea) but it's sure not C++