using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; namespace StgSharp.Data { public partial class HuffmanTree where T : struct { public Dictionary> BuildHuffmanDictionary() { Dictionary> ret = new Dictionary>(); TreeNode root = Root; HuffmanKey key = new HuffmanKey(); key = key.SetSide(KeySide.Right); InternalBuildDictionary(ret, root, key); return ret; } public void InternalBuildDictionary( Dictionary> dict, TreeNode node, HuffmanKey valueTemp ) { HuffmanKey nativeNode = new HuffmanKey(valueTemp.bitList); nativeNode.AddIndexLevel(); //检查左节点 if (node._left.Value == null) { //左节点不是叶子节点,继续搜索 InternalBuildDictionary( dict, node._left, nativeNode.SetSide(KeySide.Left)); } else { //左节点是叶子节点,添加值 dict.Add(node._left.Value.Value, nativeNode.SetSide(KeySide.Left)); } //检查右节点 if (node._right.Value == null) { //右节点不是叶子节点,继续搜索 InternalBuildDictionary( dict, node._right, nativeNode.SetSide(KeySide.Right)); } else { //右节点是叶子节点,添加值 dict.Add(node._right.Value.Value, nativeNode.SetSide(KeySide.Right)); } //这里检查自己是不是叶子节点 //但是上面已经检查过了,不需要被检查 } } public class HuffmanKey where T : struct { internal List bitList; internal BitArray code; public HuffmanKey() { bitList = new List(); bitList.Add(false); } public HuffmanKey(List former) { bitList = new List(former); } public unsafe byte[] GetBytes() { byte[] bytes = new byte[bitList.Count / 8 +1]; BitArray array = new BitArray(bitList.ToArray()); array.CopyTo(bytes, 0); return bytes; } public void Freeze() { if (code != null) { return; } bitList.RemoveAt(0); code = new BitArray(bitList.ToArray()); } public BitArray GetBitArray() { if (code == null) { List list = new List(bitList); list.RemoveAt(0); return new BitArray(list.ToArray()); } return code; } public unsafe HuffmanKey SetSide(KeySide side) { HuffmanKey newKey = new HuffmanKey(bitList); newKey.bitList[newKey.bitList.Count - 1] = (side == KeySide.Left); return newKey; } public unsafe void AddIndexLevel() { bitList.Add(true); } public bool IsSupported { get { return typeof(T) == typeof(byte) || typeof(T) == typeof(uint) || typeof(T) == typeof(ushort) || typeof(T) == typeof(ulong) || #if NET7_0_OR_GREATER typeof(T) == typeof(UInt128) || #endif typeof(T) == typeof(M128); } } public override string ToString() { string str = ""; foreach (var bit in bitList) { str += $"{bit} "; } return str; } } public enum KeySide { Left, Right } }