樹(下)課後練習題3
題目給了提示,不一定要每次都建立哈夫曼樹,而是通過比較字首碼的長度是否為最優。
那麼對於給定的一組字元和頻率(因為輸入輸出字元都是按順序的,所以沒必要存這些字元),可以不建哈夫曼樹的得到其wpl,主要是利用優先佇列模擬小頂堆,只要優先佇列中的元素個數大於1,就從中取出最小的兩個元素,wpl加上這兩個元素的和,然後再將這兩個元素的和入隊。
為什麼是這樣的?來自於合併果子問題。
如何判斷乙個同學的結果是否正確有兩個地方:
判斷其編碼的wpl是否等於最優wpl
得到wpl後,針對每個同學的結果,在輸入時,記錄下來編碼(為了判斷是否是字首碼,無二義性的),然後計算該同學編碼結果的wpl,wpl每次都加上頻率*編碼長度。
判斷這些編碼是否是無二義性的字首碼
將編碼按字串長度從小到大排序,然後依次看每乙個編碼是否是後面編碼的一部分即可
#include
#include
#include
#include
using
namespace std;
const
int maxn =
100;
priority_queue<
int, vector<
int>
, greater<
int>
> q;
//優先佇列替代小頂堆
int data[maxn]
;//存放各個元素的頻率
string prefix[maxn]
;//存放各個字首
int n, wpl =0;
bool
cmp(string s1, string s2)
bool
check()
if(wpl != wpl)
flag =
false
;//下面繼續判斷是否為字首碼
//按長度排序
sort
(prefix, prefix+n, cmp)
;for
(int i=
0; i
1; i++)}
}return flag;
}int
main()
//求出正確的wpl
while
(q.size()
>1)
// printf("%d\n", wpl);
cin>>m;
for(
int i=
0; i
)return0;
}
DS部落格作業05 樹
通過這次對樹的學習,這是第一次學習非線性結構的資料結構,之前都是學線性的,感覺有點不習慣,做題之後 感覺線性和非線性的區別也就是遍歷的方法不一樣,以前線性結構遍歷都是用迴圈,到了非線性結構遍歷則都是 用遞迴。樹結構我覺得就分為兩種多叉樹和二叉樹,二叉樹結構體都是用左右孩子,而多叉樹結構體都是孩子和 ...
DS部落格作業05 樹
說明 由於在日常提交列表中除錯過程以及碰到的問題不太明顯,所以將上機考試中的困難點列出輸入一行中綴表示式,轉換一顆二叉表示式樹,並求解.建立二叉表示式樹 建立字元棧op 樹根棧tree op.push 遍歷 str i if 是數字 依次存入樹根棧內 if 是符號 判斷 str i 與 op棧頂的優...
DS部落格作業05 樹
感覺樹的內容很難,一些邏輯比較難弄懂,而且內容比較多,所以還是得花時間去理解,樹不比先前的那些線性結構,多了很多新東西,比如帶權路徑長度,哈弗曼編碼什麼的,總之要學起來真的不容易。觀察表示式樹會發現數字字元的左孩子右孩子都是空的用於後面的表示式樹的運算 建立兩個棧乙個是樹節點的儲存型別乙個是字元儲存...