日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构之哈夫曼树

發布時間:2025/6/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构之哈夫曼树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據結構之哈夫曼樹

1.哈夫曼樹簡介

(1)?WPL?=?7*2+5*2+2*2+4*2?=?36

?

(1)?WPL?=?7*1+5*2+2*3+4*3?=?35;經過證明此為最小的WPL即為哈夫曼樹

在解決某些問題時,利用哈夫曼樹可以找到最佳判定算法,因為某些條件出現的頻率不一樣,這樣導致了同一段代碼在不同的環境下取得的效果不是最優的。

2.?哈夫曼樹的構造算法

假設有n個權值,則構造出的哈夫曼樹有n個葉子結點。?n個權值分別設為?w1、w2wn,則哈夫曼樹的構造規則為:

  (1)?w1w2wn看成是有n?棵樹的森林(每棵樹僅有一個結點)

(2)?在森林中選出兩個根結點的權值最小的樹合并,作為一棵新樹的左、右子樹,且新樹的根結點權值為其左、右子樹根結點權值之和;

  (3)從森林中刪除選取的兩棵樹,并將新樹加入森林;

(4)重復(2)、(3)步,直到森林中只剩一棵樹為止,該樹即為所求得的哈夫曼樹。

構造過程如下:

(a)?有權值為1,2,3,4四棵樹;

(b)?由于樹1,2的權值處于最小和次最小,所以選中,并合成為一棵樹,小的權值位于左邊;

(c)?3,4,(1,2?=?3)三棵樹里面選擇權值最小的和次小的,我們選中3和(1,2

合成新樹(3,(1,2=?6);

(d)?最后選出新樹(4,(3,(1,?2)))

?

(來自:http://baike.baidu.com/view/127820.htm

3.?哈夫曼樹具體實現

需要考慮的問題:

(1)?用什么樣的存儲結構;

(2)?怎么選擇選擇最小和次小權值的樹;

(3)?怎么存放合成的新樹

如果我們采用

Struct?node

{

Int?key;

Struct?node?*l;

Struct?node?*r;

}

的存儲結構的話,可以采用數組的鏈式結構,并設計標記數組如下:

(我們以4個初始樹為例子)

標記數組:(有則標記為1,否則為0

Struct?node?n1

Struct?node?n1

Struct?node?n1

Struct?node?n1

存儲數組

Struct?node?n1

Struct?node?n1

Struct?node?n1

Struct?node?n1

第一次選擇為1,2樹,合成新樹,我們可以統一放在最小樹的位置上(也可以放在大樹位置上),所以新樹放于樹1?的位置并更新其權值為兩者之和,其狀態為:

標記數組:(有則標記為1,否則為0

1

0

1

1

存儲數組

Struct?node?n1

Free()

Struct?node?n1

Struct?node?n1

這樣存儲結構的問題解決了,其實做到這里我們應該比較清楚后面怎么做了,當然選擇出最小值和次小值為比較簡單的算法了。

例:設有8個字符{ABCDEFGH},其概率為{0.050.290.070.080.140.230.03,0.11},設其權值用整數表示為?{529781423311},其哈夫曼樹如圖1所示。

?

實現代碼如下:

#include?<stdio.h>

#include?<stdlib.h>

#include?<string.h>

struct?node?

{

int?key;

struct?node?*l;

struct?node?*r;

};

typedef?struct?node?*pnode;

int?mark[100];

struct?node??huffman[100];

void?PrintNode(const?pnode?node)

{

printf("key?=?%d?\n",?node->key);

}

void?PreOrder(pnode?T)

{

if(T)

???{

???PrintNode(T);

???PreOrder(T->l);????????

???PreOrder(T->r);

????}

??

}

void?Select(int?*mark,?struct?node?*huffman,?int?size,?int?*choose)??

{?

????int?i;?

????for(i?=?0;?i<?size;?i++)

{

if(mark[i])

{

choose[0]?=?i;

i++;

break;

}

}

choose[1]?=?choose[0];

????for(;i?<?size;i++)?

????{?

????????if(mark[i])?

????????{?

????????????if(huffman[choose[0]].key?>=?huffman[i].key)?

????????????{?

????????????choose[1]?=?choose[0];

????????????????choose[0]?=?i;?

????????????}?

????????????else?if(huffman[choose[1]].key?>?huffman[i].key)????choose[1]?=?i;?

????????}?

????}?

}?

void?Choose(int?*mark,?struct?node?*huffman,?int?size,?int?*choose)

{

int?i;

int?minkey?=?0;

int?tkey?=?0;

int?temp?=?0;

for(i?=?0;?i<?size;?i++)

{

if(mark[i])

{

minkey?=?i;

i++;

break;

}

}

tkey?=?minkey;

for(;?i<?size;?i++)

{

if(mark[i])

{

if(huffman[i].key?<?huffman[minkey].key)

{

tkey?=?minkey;

minkey?=?i;

}

if(tkey?==?minkey)

tkey?=?i;

if(huffman[tkey].key?>?huffman[i].key?&&?i?!=?minkey)

{

tkey?=?i;

}

}

}

choose[0]?=?minkey;

choose[1]?=?tkey;

}

pnode?HuffmanTree(int?*mark,?struct?node?*huffman,?int?size)

{

int?choose[2];

int?i;

pnode?mynode;?

for(i?=?0;?i?<?size-1;?i++)

{

Select(mark,?huffman,?size,?choose);

mynode?=?(pnode)malloc(sizeof(struct?node));

mynode->key?=?huffman[choose[0]].key+huffman[choose[1]].key;//更新key

mynode->l?=?(pnode)malloc(sizeof(struct?node));

mynode->l->key?=?huffman[choose[0]].key;

mynode->l->l?=?huffman[choose[0]].l;

mynode->l->r?=?huffman[choose[0]].r;

mynode->r?=?&huffman[choose[1]];

huffman[choose[0]]?=?*mynode;

mark[choose[1]]?=?0;

free(mynode);

}?

return?&huffman[choose[0]];

}

int?main(void)

{

int?key[8]?=?{5,29,7,8,14,23,3,11};

int?i;

pnode?huffmantree;

memset(mark,?-1,?sizeof(mark));

memset(huffman,?0,?sizeof(huffman));

for(i?=?0;?i?<?8;?i++)

{

huffman[i].key?=?key[i];

}

huffmantree?=?HuffmanTree(mark,?huffman,?8);

PreOrder(huffmantree);

return?0;

}

總結

以上是生活随笔為你收集整理的数据结构之哈夫曼树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。