給定n個權值作為n個葉子結點,構造一棵二叉樹,若該樹的帶權路徑長度達到最小,稱這樣的二叉樹為最優二叉樹,也稱為哈夫曼樹(huffman tree)。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。
結構定義:
template
<
typename elemtype>
struct huffmannode
;template
<
typename elemtype>
using huffmantree = huffmannode*;
template
<
typename elemtype>
struct huffmancode
;
基本操作:
初始化:建立節點陣列,填入初始節點資訊,其他節點資訊初始化
template
<
typename elemtype>
void
inithuffmantree
(huffmantree
& ht, elemtype* data,
int* weight,
int len)
//初始化huffmantree
p = ht;
for(
int i =
0; i < len_ht; i++
)//父子節點歸0
}
建立:遍歷所有未被選擇的初始節點,尋找其中權重最小的兩個節點建立結合成一顆樹,直到只剩乙個節點未被選擇,剩下的這個結果就是huffman樹的根節點;選擇未被選擇的節點中權重最小的兩個適合寫成乙個函式
尋找未被選擇的節點中權重最小的兩個:通過兩次遍歷可以尋找到權重最小的點,再來兩次遍歷就可以找到次小的節點;因為返回值需要兩個,所有適合通過引用返回結果
template
<
typename elemtype>
void
select
(huffmantree
& ht, huffmantree
& min, huffmantree
& smin,
int len)
//選擇權重最小的兩項
p++;}
p = ht;
//指標歸位
for(
int i =
0; i < len; i++
)//第二次遍歷
p++;}
min = temp;
//最小權重
p = ht;
//指標歸位
for(
int i =
0; i < len; i++
)//第一次遍歷
p++;}
p = ht;
//指標歸位
for(
int i =
0; i < len; i++
)//第二次遍歷
p++;}
smin = temp;
}
建立:
template
<
typename elemtype>
void
createhuffmantree
(huffmantree
& ht, elemtype* data,
int* weight,
int len)
//建立huffmantree
}
每個初始節點編碼:借助棧,尋找父節點,左「0」右「1」對每個節點編碼,編碼結果存在陣列中方便查詢
棧參考這裡
對存放編碼的陣列的初始化:
template
<
typename elemtype>
void
inithuffmancode
(huffmancode
*& hc, elemtype* data,
int len)
//初始化編碼
}
每個初始節點編碼:
template
<
typename elemtype>
void
huffmanencoding
(huffmancode
*& hc, huffmantree
& ht, elemtype* data,
int* weight,
int len)
//huffman編碼
while(!
isempty
(s))
t++;//下一葉子的編碼
}}
編碼與解碼資訊:通過查詢存放編碼的陣列,對輸入的資訊進行編碼,或對輸入的編碼進行解碼;查詢編碼應該單獨寫乙個函式
查詢編碼:若找到則返回索引
template
<
typename elemtype>
intcomparehc
(huffmancode
* hc,
int len, string str)
//比較str是否是hc中的乙個編碼
編碼資訊:
template
<
typename elemtype>
string encodemessage
(huffmancode
* hc, elemtype* msg,
int len)
//編碼資訊
return result;
}
解碼資訊:
template
<
typename elemtype>
string decodemessage
(huffmancode
* hc,
int len, string code)
//huffman解碼
}return result;
}
測試:
void
testhuffmantree()
;huffmanencoding
(hc, ht, data, weight, len)
;printhuffmantree
(hc, ht, len)
; cout << endl;
cout <<
"下面開始測試編碼"
<< endl;
cout <<
"輸入要編碼的內容:"
;char
* msg =
newchar
[100];
cin >> msg;
char
* temp = msg;
int length =0;
while(*
(temp++))
length++
; cout <<
encodemessage
(hc, msg, length)
<< endl;
cout << endl;
cout <<
"下面開始測試解碼"
<< endl;
cout <<
"輸入要解碼的內容:"
; string code;
cin >> code;
cout <<
decodemessage
(hc, len, code)
<< endl;
cout << endl;
system
("pause");
}
結果:
資料結構 霍夫曼樹
帶權路徑長度最小的樹,常用於資料通訊中。構造霍夫曼樹演算法 設給定的一組權值為,據此生成森林f f 中的沒棵二叉樹只有乙個帶權為w1的根節點 i 1,2,n 在f中選取兩棵根節點的權值最小和次小的二叉樹作為左右構造一棵新的二叉樹,新二叉樹根節點的權值為其左 右子樹根節點的權值之和。在f中刪除這兩棵最...
資料結構 Huffman樹
參照書上寫的huffman樹的 結構用的是線性儲存的結構 不是二叉鍊錶 裡面要用到查詢最小和第二小 理論上錦標賽法比較好 但是實現好麻煩啊 考慮到資料量不是很大 就直接用比較笨的先找最小 去掉最小再找第二小的方法了。include include include typedef struct htn...
資料結構 Huffman樹
參照書上寫的huffman樹的 結構用的是線性儲存的結構 不是二叉鍊錶 裡面要用到查詢最小和第二小 理論上錦標賽法比較好 但是實現好麻煩啊 考慮到資料量不是很大 就直接用比較笨的先找最小 去掉最小再找第二小的方法了。include include include typedef struct htn...