哈弗曼編碼演算法(簡單鏈表法)

來源:互聯網
上載者:User

演算法代碼如下:

public class HuffmanNode    {        public char Char { get; set; }        public int Frequency { get; set; }        //用於構造哈弗曼樹        internal HuffmanNode LeftChild { get; set; }        internal HuffmanNode RightChild { get; set; }        //用於構造鏈表        internal HuffmanNode NextSibling { get; set; }        public string HuffmanCode {get;set;}        public HuffmanNode(char Char,int Freq)        {            this.Char = Char;            this.Frequency = Freq;        }    }    public class HuffmanAlgorithms    {        /// <summary>        /// 進行哈弗曼編碼,編碼過程中不改變Nodes節點,僅改變一些域。        /// </summary>        /// <param name="Nodes"></param>        public static void HuffmanCode(HuffmanNode[] Nodes)        {            if (Nodes == null || Nodes.Length == 0)            {                return;            }            #region 這個處理可以不要            if (Nodes.Length == 1)            {                Nodes[0].HuffmanCode = "0";                return;            }            if (Nodes.Length == 2)            {                Nodes[0].HuffmanCode = "0";                Nodes[1].HuffmanCode = "1";                return;            }            #endregion            HuffmanNode theHead = null;            //用插入排序演算法,建立升序節點鏈表O(n^2)            for (int i = 0; i < Nodes.Length;i++ )            {                InsertNode(ref theHead, Nodes[i]);            }            //建立Huffman樹,採用貪婪法,每次取鏈表中最小的兩個(前兩個).            HuffmanNode theTmp1 = null;            HuffmanNode theTmp2 = null;            theTmp1 = theHead;            if (theHead != null)            {                theTmp2 = theHead.NextSibling;            }            //鏈表裡有兩個則操作,則繼續建樹,否則樹建立完成,退出迴圈.O(n*lgn)            while (theTmp1 != null && theTmp2 != null)            {                //建立一個內節點包含當前鏈表中兩個最小元素,這個節點的頻率是這兩個元素的頻率之和.                HuffmanNode theParent = new HuffmanNode('\0', theTmp1.Frequency + theTmp2.Frequency);                theParent.LeftChild = theTmp1;                theParent.RightChild = theTmp2;                //除掉當前兩個最小元素,並插入建立節點.                theHead = theTmp2.NextSibling;                //將建立立的內節點插入當前鏈表.                InsertNode(ref theHead, theParent);                                theTmp1 = theHead;                if (theHead != null)                {                    theTmp2 = theHead.NextSibling;                }            }            //採用樹的先序遍曆進行編碼.結果存放在節點的編碼域中.o(n)            HuffmanCode(theHead, "");            //清理臨時域,保證記憶體釋放.o(n)            foreach (var node in Nodes)            {                node.LeftChild = null;                node.NextSibling = null;                node.RightChild = null;            }        }        /// <summary>        /// 利用樹的先序遍曆進行編碼,實際上有效都是葉子節點,葉子節點都在Nodes數組中。        /// </summary>        /// <param name="ANode"></param>        /// <param name="StrCode"></param>        private static void HuffmanCode(HuffmanNode ANode, string StrCode)        {            if (ANode != null)            {                ANode.HuffmanCode = StrCode;                if (ANode.LeftChild != null)                {                    HuffmanCode(ANode.LeftChild, StrCode + "0");                }                if (ANode.RightChild != null)                {                    HuffmanCode(ANode.RightChild, StrCode + "1");                }            }        }        /// <summary>        /// 將節點Node插入到鏈表AHead中去,並升序排列.        /// </summary>        /// <param name="AHead"></param>        /// <param name="Node"></param>        private static void InsertNode(ref HuffmanNode AHead,HuffmanNode Node)        {            HuffmanNode theTmp1 = AHead;            HuffmanNode theTmp2 = null;            while (theTmp1 != null && theTmp1.Frequency < Node.Frequency)            {                theTmp2 = theTmp1;                theTmp1 = theTmp1.NextSibling;            }            if (theTmp2 == null)            {                AHead = Node;            }            else            {                theTmp2.NextSibling = Node;             }            Node.NextSibling = theTmp1;        }    }

PS:這個演算法利用最小堆效率要高些,在O(nlgn),這裡的演算法還是O(n^2),符合插入排序演算法的時間複雜度.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.