![數(shù)據(jù)結(jié)構(gòu)第三次實驗報告_第1頁](http://file4.renrendoc.com/view12/M0B/0D/38/wKhkGWXikB2AW4B-AALP3fuNsn4869.jpg)
![數(shù)據(jù)結(jié)構(gòu)第三次實驗報告_第2頁](http://file4.renrendoc.com/view12/M0B/0D/38/wKhkGWXikB2AW4B-AALP3fuNsn48692.jpg)
![數(shù)據(jù)結(jié)構(gòu)第三次實驗報告_第3頁](http://file4.renrendoc.com/view12/M0B/0D/38/wKhkGWXikB2AW4B-AALP3fuNsn48693.jpg)
![數(shù)據(jù)結(jié)構(gòu)第三次實驗報告_第4頁](http://file4.renrendoc.com/view12/M0B/0D/38/wKhkGWXikB2AW4B-AALP3fuNsn48694.jpg)
![數(shù)據(jù)結(jié)構(gòu)第三次實驗報告_第5頁](http://file4.renrendoc.com/view12/M0B/0D/38/wKhkGWXikB2AW4B-AALP3fuNsn48695.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
數(shù)據(jù)結(jié)構(gòu)實驗報告實驗三哈夫曼樹實驗班級:_計2-1___姓名:_依力夏提江·艾買爾__學(xué)號:_12101020129_實驗?zāi)康模菏煜し蔷€性結(jié)構(gòu)的特點,掌握非線性結(jié)構(gòu)的存儲方式及各種操作的實現(xiàn)方法,同時對自頂向下的程序設(shè)計方法、應(yīng)用程序界面的設(shè)計、非線性結(jié)構(gòu)的文件存儲方法等方面的輯程技術(shù)進行訓(xùn)練。問題描述:利用哈夫曼編碼進行信息通訊可以大大提高信道利用率,縮短信息傳輸時間,降低傳輸成本。但是,這要求在發(fā)送端通過一個編碼系統(tǒng)對待傳數(shù)據(jù)預(yù)先編碼;在接收端將傳來的數(shù)據(jù)進行譯碼(復(fù)原)。對于雙工信道(即可以雙向傳輸信息的信道),每端都需要一個完整的編/譯碼系統(tǒng),試為這樣的信息收發(fā)站寫一個哈夫曼編譯碼系統(tǒng)?;疽螅阂粋€完整的系統(tǒng)應(yīng)具有以下功能:(1)I:初始化。從終端讀入字符集大小n,及n個字符和n個權(quán)值,建立哈夫曼樹,并將其存于文件hfmtree中。(2)C:編碼。利用已建好的哈夫曼樹(如不在內(nèi)存,則從文件hfmtree中讀入),對文件tobetrans中的正文進行編碼,然后將結(jié)果存入文件codefile中。(3)D:譯碼。利用已建好的哈夫曼樹將文件codefile中的代碼進行譯碼,結(jié)果存入文件textfile中。(4)P:打印代碼文件。將文件codefi1e以緊湊格式顯示在終端上,每行50個代碼。同時將此字符形式的編碼文件寫入文件codeprint中。(5)T:打印哈夫曼樹。將已在內(nèi)存中的哈夫曼樹以直觀的方式(樹或凹凸表形式)顯示在屏幕上,同時將此字符形式的哈夫曼樹寫入文件treeprint中。需求分析:(包括對問題的理解,解決問題的策略、方法描述)本程序?qū)崿F(xiàn)了使用赫夫曼編碼壓縮數(shù)據(jù);輸入一串字符串sourceCode——為方便理解,暫時要求字符串只包含大寫字母和空格,如果你愿意,很容易就可以推廣到所有的字符——計算出字符串中各個字母的權(quán)重,然后對其進行赫夫曼編碼,輸出赫夫曼樹。將赫夫曼樹的葉子結(jié)點存儲到有序二叉樹中,輸出原字符串經(jīng)壓縮后得到的用’0’和’1編碼譯碼成功!最后銷毀有序二叉樹和赫夫曼樹。系統(tǒng)設(shè)計:(包括數(shù)據(jù)結(jié)構(gòu)定義、抽象出基本操作描述、主程序模塊處理過程描述)typedefcharElemType;//定
typedefstructsNode
{
doubleweight;
ElemTypedata;
}*Source;
typedefstructhNode
{
doubleweight;
ElemTypedata;
intlc,rc;
}*HuffmanTree;
typedefstructcNode
{
ElemTypedata;
stringstr;
structcNode*lc,*rc;
}*Btree;
HuffmanTreeCreateHuffmanTree(constSourcew,intn);//創(chuàng)建一棵赫夫曼樹
voidBuildHeap(HuffmanTreet,intn);//構(gòu)造一個二叉堆;小頂堆
voidPercDown(HuffmanTreet,intpos,intn);//構(gòu)造二叉堆的功能子函數(shù)
voidDeleteMin(HuffmanTreet,intlen);/*刪除二叉堆的根,并通過上移使得新得到的序列仍為二叉堆*/
voidInsertHfNode(HuffmanTreet,intlen,structhNodex);/*把x插入到原長度為len的二叉堆*/
voidPreorder(HuffmanTreet,intp);//先序遍歷赫夫曼樹
voidPostorder(Btree&t,HuffmanTreea,intn);/*后序遍歷赫夫曼樹,并記錄葉子結(jié)點編碼*/
boolInsertBtNode(Btree&t,Btrees);//向一個二叉排序樹t中插入一個結(jié)點s
voidInorder(Btreet);//中序遍歷二叉排序樹
BtreeSearch(Btreep,ElemTypedata);//查找值為data的結(jié)點的遞歸算法
stringCoding(strings,Btreet);/*利用記錄了葉子結(jié)點編碼的排序二叉樹,對sourceCode進行編碼,返回編碼后的字符串*/
stringDecode(strings,HuffmanTreehT);//利用赫夫曼樹對destCode進行解碼
voidDestroyBTree(Btree&t);//銷毀一棵二叉排序樹
voidDestroyHfmanTree(HuffmanTree&t,intn);//銷毀一棵赫夫曼樹主函數(shù):intmain()
{
stringsourceCode;
getline(cin,sourceCode,’\n’);
intn=sourceCode.size();
constintMAX=27;//原碼由26個大寫字母加空格組成
Sourcew=newstructsNode[MAX];
//讀取各個字母并初始化權(quán)重
w[MAX-1].data=’’;
w[MAX-1].weight=0;
for(inti=MAX-2;i>=0;i--)
{
w[i].data=’A’+i;
w[i].weight=0;
}
//讀取各個字母的權(quán)重
for(inti=0;i<n;i++)
{
if(sourceCode[i]==’’)
w[26].weight++;
else
w[sourceCode[i]-’A’].weight++;
}
//獲取出現(xiàn)了的大寫字母和空格
n=0;
for(inti=0;i<MAX;i++)
{
if(w[i].weight>0)
w[n++]=w[i];
}
////直接輸入原碼和權(quán)重
//for(inti=0;i<n;i++)
//{
//cin>>w[i].weight>>w[i].data;
//}
for(inti=0;i<n;i++)
{
cout<<w[i].weight<<""<<w[i].data<<endl;
}
HuffmanTreehT=CreateHuffmanTree(w,n);//構(gòu)造赫夫曼樹
//for(inti=1;i<2*n;i++)
//cout<<hT[i].weight<<"";
//cout<<endl;
//先序遍歷赫夫曼樹,并輸出結(jié)點權(quán)重和葉子結(jié)點的data
Preorder(hT,1);
cout<<endl;
//后序遍歷赫夫曼樹,并記錄葉子結(jié)點編碼
BtreebT=NULL;
Postorder(bT,hT,n);
//中序遍歷記錄了葉子結(jié)點編碼的排序二叉樹
Inorder(bT);
//利用記錄了葉子結(jié)點編碼的排序二叉樹,對sourceCode進行編碼
stringdestCode=Coding(sourceCode,bT);
cout<<destCode<<endl;
//利用赫夫曼樹對destCode進行解碼
stringobjCode=Decode(destCode,hT);
cout<<objCode<<endl;
DestroyBTree(bT);//銷毀二叉排序樹
//Inorder(bT);//再輸出試試看
DestroyHfmanTree(hT,n);//銷毀赫夫曼樹
//Preorder(hT,1);//再輸出試試看
system("pause");
return0;
}調(diào)試分析:(包括調(diào)試過程中對原設(shè)計的修改,以及遇到的問題和解決的方法)構(gòu)造哈夫曼非常簡單,將所有的節(jié)點放到一個隊列中,用一個節(jié)點替換兩個頻率最低的節(jié)點,新節(jié)點的頻率就是這兩個節(jié)點的頻率之和。這樣,新節(jié)點就是兩個被替換節(jié)點的父節(jié)點了。如此循環(huán),直到隊列中只剩一個節(jié)點(樹根)。不過因為自己技術(shù)還不嫻熟所以遇到了很多麻煩,而且也參考了別人的資源,下圖輸出方式安分布方式給出了哈夫曼樹狗仔的過程!測試結(jié)果:(輸入的測試數(shù)據(jù)及運行結(jié)果、正確性、在線測試情況)基本操作的實現(xiàn):(對各基本操作實現(xiàn)的描述)(后面可加頁)//創(chuàng)建一棵赫夫曼樹
HuffmanTreeCreateHuffmanTree(constSourcew,intn)
{
HuffmanTreehT=newstructhNode[2*n];//第一個結(jié)點不用
for(inti=0;i<n;i++)
{
hT[i+1].data=w[i].data;
hT[i+1].weight=w[i].weight;
hT[i+1].lc=hT[i+1].rc=0;
}
BuildHeap(hT,n);//構(gòu)造一個二叉堆;小頂堆
structhNodeadd;
intleft=n;
intright=n;
while(left>1)
{
hT[++right]=hT[1];
add.weight=hT[1].weight;
add.lc=right;//存儲左孩子下標(biāo)
DeleteMin(hT,left--);
hT[left+1]=hT[1];
add.weight+=hT[1].weight;
add.rc=left+1;//存儲右孩子下標(biāo)
DeleteMin(hT,left--);
InsertHfNode(hT,++left,add);
//for(inti=1;i<=right;i++)
//cout<<hT[i].weight<<"";
//cout<<endl;
//system("pause");
}
returnhT;
}
//構(gòu)造一個二叉堆;小頂堆
voidBuildHeap(HuffmanTreet,intlen)
{
for(inti=len/2+len%2;i>0;i--)
{
PercDown(t,i,len);
}
}
//構(gòu)造二叉堆的功能子函數(shù)
voidPercDown(HuffmanTreet,intpos,intlen)
{
intchild;
structhNodemin=t[pos];
while(pos*2<=len)
{
child=pos*2;
if(child!=len&&t[child+1].weight<t[child].weight)
child++;
if(min.weight>t[child].weight)
t[pos]=t[child];
else
break;
pos=child;
}
t[pos]=min;
}
//刪除二叉堆的根,并通過上移使得新得到的序列仍為二叉堆
voidDeleteMin(HuffmanTreet,intlen)
{
structhNodelast=t[len--];//二叉堆的最后一個元素
intchild,pos=1;
while(pos*2<=len)//把二叉堆的某些元素往前移,使得新得到的序列仍為二叉堆
{
child=pos*2;
if(child!=len&&t[child+1].weight<t[child].weight)//若i有右兒子,且右兒子小于左兒子,c指向右兒子
child++;
if(last.weight>t[child].weight)//若i的小兒子小于二叉堆的最后一個元素,把其移到i的位置
t[pos]=t[child];
else
break;
pos=child;
}
t[pos]=last;//把二叉堆的最后一個元素放到適當(dāng)?shù)目瘴唬藭r得到的序列仍為二叉堆
}
//把x插入到原長度為len的二叉堆
voidInsertHfNode(HuffmanTreet,intlen,structhNodex)
{
inti;
for(i=len;i/2>0&&t[i/2].weight>x.weight;i/=2)
t[i]=t[i/2];
t[i]=x;
}
//后序遍歷赫夫曼樹,并記錄葉子結(jié)點編碼
voidPostorder(Btree&t,HuffmanTreea,intn)
{
int*stack=newint[n];
int*tag=newint[n];
char*buf=newchar[n];
boolflag=true;
inttop=-1;
intp=1;
while(a[p].lc>0||top>=0)
{
while(a[p].lc>0)//先一直尋找左孩子
{
flag=true;//此時p指向的是新葉子(未輸出過的葉子)
stack[++top]=p;//結(jié)點入棧
p=a[p].lc;
tag[top]=0;//表示右孩子沒有被訪問
buf[top]=’0’;//左孩子標(biāo)記’0’
}
if(flag)//如果p指向的是新葉子
{
//cout<<a[p].data<<":";//輸出葉子結(jié)點
//for(inti=0;i<=top;i++)
//cout<<buf[i];
//cout<<endl;
Btrees=newstructcNode;
s->data=a[p].data;
for(inti=0;i<=top;i++)
s->str+=buf[i];
s->lc=s->rc=NULL;
if(!(InsertBtNode(t,s)))//插入一個結(jié)點s
deletes;
}
if(top>=0)//所有左孩子處理完畢后
{
if(tag[top]==0)//如果右孩子沒有被訪問
{
flag=true;//此時p指向的是新葉子(未輸出過的葉子)
p=stack[top];//讀取棧頂元素,但不退棧,因為要先輸出其右孩子結(jié)點
p=a[p].rc;
tag[top]=1;//表示右孩子被訪問,下次直接退棧
buf[top]=’1’;//右孩子標(biāo)記’1’
}
else//棧頂元素出棧
{
flag=false;//此時p指向的是舊葉子(已輸出過的葉子),不再輸出
top--;
}
}
}
}
//先序遍歷赫夫曼樹
voidPreorder(HuffmanTreet,intp)
{
if(t==NULL)
return;
if(t[p].lc>0)
{
cout<<t[p].weight<<endl;
Preorder(t,t[p].lc);//遍歷左子樹
Preorder(t,t[p].rc);//遍歷右子樹
}
else
cout<<t[p].weight<<""<<t[p].data<<endl;
}
//向一個二叉排序樹t中插入一個結(jié)點s
boolInsertBtNode(Btree&t,Btrees)
{
if(t==NULL)
{
t=s;
returntrue;
}
elseif(t->data>s->data)//把s所指結(jié)點插入到左子樹中
returnInsertBtNode(t->lc,s);
elseif(t->data<s->data)//把s所指結(jié)點插入到右子樹中
returnInsertBtNode(t->rc,s);
else//若s->data等于b的根結(jié)點的數(shù)據(jù)域之值,則什么也不做
returnfalse;
}
//中序遍歷二叉排序樹
voidInorder(Btreet)
{
i
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2031年中國活化凈水器行業(yè)投資前景及策略咨詢研究報告
- 2025至2031年中國串心光腳線行業(yè)投資前景及策略咨詢研究報告
- 2025至2031年中國A/C群腦膜炎球菌結(jié)合疫苗行業(yè)投資前景及策略咨詢研究報告
- 2025至2030年鋼釘電線卡項目投資價值分析報告
- 2025至2030年潔陰噴劑項目投資價值分析報告
- 2025至2030年低溫制冷用雙螺桿壓縮機項目投資價值分析報告
- 影樓員工勞動合同書
- 開發(fā)商精裝修合同范本
- 造價咨詢廉潔制度及咨詢服務(wù)合同
- 全國合作招生服務(wù)合同書
- 新生兒的護理 新生兒科課件
- 麥當(dāng)勞市場調(diào)研
- 《電機與電氣控制(第三版)》 課件全套 課題1-6 直流電機的應(yīng)用- 常用機床電氣控制線路的安裝與調(diào)試
- 視頻監(jiān)控維保項目投標(biāo)方案(技術(shù)標(biāo))
- 2024標(biāo)準(zhǔn)版安全生產(chǎn)責(zé)任制培訓(xùn)記錄
- 中英旅游文本用詞的共同特點及其翻譯
- Meta分析的步驟與實例分析
- 城市區(qū)域環(huán)境噪聲監(jiān)測實驗報告
- MBTI量表完整版本
- 護理操作-吸痰
- 中醫(yī)適宜技術(shù)-腕踝針
評論
0/150
提交評論