Ejemplo n.º 1
0
		private static int GetTotalBits(Node root)
		{
			var queue = new Queue<Node>();
			queue.Enqueue(root);

			var totalBits = 0;

			while (queue.Count > 0)
			{
				var node = queue.Dequeue();

				if (node.Left == null && node.Right == null)
				{
					continue;
				}

				totalBits += node.Frequency;

				if (node.Left != null &&
					node.Left.Left != null &&
					node.Left.Right != null)
				{
					queue.Enqueue(node.Left);
				}

				if (node.Right != null &&
					node.Right.Left != null &&
					node.Right.Right != null)
				{
					queue.Enqueue(node.Right);
				}
			}

			return totalBits;
		}
Ejemplo n.º 2
0
		public void Build(string text)
		{
			if (text == null)
			{
				throw new ArgumentNullException(nameof(text));
			}

			_root = null;
			var frequencies = new Dictionary<char, int>();
			_codes.Clear();

			foreach (var t in text)
			{
				int frequency;
				if (frequencies.TryGetValue(t, out frequency) == false)
				{
					frequency = 0;
				}
				frequencies[t] = frequency + 1;
			}

			var nodes = frequencies.Select(
				symbol => new Node
				{
					Symbol = symbol.Key,
					Frequency = symbol.Value,
				}).ToList();

			while (nodes.Count > 1)
			{
				var orderedNodes = nodes
					.OrderBy(n => n.Frequency).ToList();

				if (orderedNodes.Count >= 2)
				{
					var taken = orderedNodes.Take(2).ToArray();
					var first = taken[0];
					var second = taken[1];

					var parent = new Node
					{
						Symbol = '\0',
						Frequency = first.Frequency + second.Frequency,
						Left = first,
						Right = second,
					};

					nodes.Remove(first);
					nodes.Remove(second);
					nodes.Add(parent);
				}

				_root = nodes.FirstOrDefault();
			}

			foreach (var frequency in frequencies)
			{
				var bits = Traverse(_root, frequency.Key, new List<bool>());
				
				if (bits == null)
				{
					throw new InvalidOperationException(string.Format(
						"could not traverse '{0}'", frequency.Key));
				}

				_codes.Add(frequency.Key, new BitArray(bits.ToArray()));
			}

			TotalBits = GetTotalBits(_root);
		}
Ejemplo n.º 3
0
		private static List<bool> Traverse(Node node, char symbol, List<bool> data)
		{
			if (node.Left == null && node.Right == null)
			{
				return symbol == node.Symbol ? data : null;
			}

			if (node.Left != null)
			{
				var path = new List<bool>();
				path.AddRange(data);
				path.Add(false);

				var left = Traverse(node.Left, symbol, path);

				if (left != null)
				{
					return left;
				}
			}

			if (node.Right != null)
			{
				var path = new List<bool>();
				path.AddRange(data);
				path.Add(true);

				var right = Traverse(node.Right, symbol, path);

				if (right != null)
				{
					return right;
				}
			}

			return null;
		}