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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

数据结构与算法(6-5)二叉树的应用--哈夫曼树与哈夫曼编码

發(fā)布時間:2023/11/27 生活经验 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法(6-5)二叉树的应用--哈夫曼树与哈夫曼编码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

哈夫曼編碼(最優(yōu)二叉樹)

一、優(yōu)勢:縮短電文長度

二、思想:

三、過程:?

四、圖解實現(xiàn)過程:?

五、總代碼?


哈夫曼編碼(最優(yōu)二叉樹)


一、優(yōu)勢:縮短電文長度

?二、思想:

????????獲取每個字符出現(xiàn)的頻率,用一個大小為[256]的數(shù)組保存(因為ASCII碼是256個),最后作為每個字符的權重權重越大,意味著出現(xiàn)頻率越大,希望它的碼長越短,這樣總體電文最小。最后把這些字符(不重復部分)、權重依次放入結點中,把這些結點作為一個個元素,從小到大依次組成哈夫曼樹。

三、過程:?

先統(tǒng)計出字符出現(xiàn)的頻率,作為其權重。
編碼保存:把每個不重復的字符頻率作為權重,用二叉樹進行排序,二叉樹上面的字符權重大(出現(xiàn)頻率高),編碼的碼長短,下面的字符權重小(出現(xiàn)頻率低),編碼碼長長。
編碼:輸入字符,遍歷整個二叉樹,對比是否和葉子結點相同,是則保存編碼。(左0右1)
譯碼:輸入二進制碼,在二叉樹中走一遍,走到葉子結點即為需要保存的編碼。(左0右1)

(向左走為0,向右走為1)

四、圖解實現(xiàn)過程:?

五、總代碼?

//哈夫曼編碼
//優(yōu)勢:縮短電文長度
//先統(tǒng)計出字符出現(xiàn)的頻率,作為其權重。
//編碼保存:把每個不重復的字符作為權重,用二叉樹進行排序,二叉樹上面的字符權重高(出現(xiàn)頻率高),編碼的碼長短,
//下面的字符權重小(出現(xiàn)頻率低),編碼碼長長
//編碼:輸入字符,遍歷整個二叉樹,對比是否和葉子結點相同,是則保存編碼
//譯碼:輸入二進制碼,在二叉樹中走一遍,走到葉子結點即為需要保存的編碼。
#include<iostream>
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
using namespace std;#define MAXSIZE 100char str[MAXSIZE];						//要編碼保存的電文
char str_en[MAXSIZE];					//編碼時輸入的電文
char str_de[MAXSIZE];					//解碼時輸出的電文
int code_de[MAXSIZE];				//解碼時存儲
int frequency[256] = { 0 };			//統(tǒng)計各字符出現(xiàn)頻率
int flag_c[256] = { 0 };					//只存儲一次,判斷是否第一次出現(xiàn)
int length = 0;								//數(shù)組總長度
int LENGTH = 0;							//葉子結點長度
int sumFrequency = 0;					//權重之和
int index_s = 0;							//字符串數(shù)組
int code[64];								//編碼
int index_c = -1;							//編碼數(shù)組
int step = 0;									//編碼/譯碼步數(shù)(從哈夫曼樹的根往后下走)
int sumCode[4 * MAXSIZE];			//總編碼
int flag_exit = 0;							//退出符號
int index = 0;								//譯碼數(shù)組
int decode_length;						//譯碼數(shù)組長度//樹元素
typedef struct Tnode
{char data;									//存放數(shù)據(jù)int frequency;							//權重(出現(xiàn)的頻率)struct Tnode* lchild, * rchild;	//左右孩子int code[64];							//每個字符的哈夫曼碼int code_length;						//編碼長度
}Tnode;
Tnode T[MAXSIZE];						//存放各結點
Tnode* hfmTree;							//哈夫曼根結點
Tnode* Pre;									//存放前一個結點//輸入字符串
void Input()
{cout << "請輸入需要編碼并保存編碼的電文:\n";gets_s(str, 100);
}//輸入待編碼數(shù)組
void Encode_Input()
{cout << "請輸入需要編碼的電文:\n";getchar();gets_s(str_en, MAXSIZE);
}//輸出編碼后的數(shù)組
void Encode_Output()
{int i = 0;//下標for (i = 0; i <= index_c; i++){cout << sumCode[i];}cout << endl;
}//輸入待譯碼數(shù)組
void Decode_Input()
{int i = 0;char ch = ' ';step = 0;cout << "請輸入需要譯碼的二進制碼:\n";index = 0;getchar();									//吸收空格//讀取每位字符,挨個化整存入整形數(shù)組while (ch != '\n')						//把每位字符保存到數(shù)組(換行退出){ch = getchar();						//讀取一位字符if (ch != '\n')code_de[i++] = ch - 48;	//字符化整}decode_length = i;					//譯碼數(shù)組長度
}//獲取權重
void GetFrequency()
{int i = 0;//統(tǒng)計字符頻率for (i = 0; i < strlen(str); i++){frequency[str[i]]++;					//頻率表中對應字符出現(xiàn)數(shù)值+1}
}//創(chuàng)建樹節(jié)點
void CreateTnode()
{int i = 0, count = 0;//添加字符和頻率到樹結構體數(shù)組中for (i = 0; i < strlen(str); i++){if (flag_c[str[i]] == 0)				//首次出現(xiàn){flag_c[str[i]] = 1;					//標志出現(xiàn)過T[count].data = str[i];T[count].frequency = frequency[str[i]];T[count].lchild = NULL;T[count].rchild = NULL;sumFrequency += T[count].frequency;		//計算葉子結點總權重count++;}}LENGTH = count;length = count;
}//獲取最小值						/***********注:要整體替換,否則后面會出現(xiàn)混亂**********/
Tnode Getmin()
{int i, j, max = 0;Tnode temp;//選擇排序(權重從高到低)(最后的一個最小)for (i = 0; i < length; i++){max = i;for (j = i; j < length; j++){if (T[j].frequency > T[max].frequency)max = j;}if (max != i){temp = T[i];								//整體替換T[i] = T[max];T[max] = temp;}}return T[--length];			//取出最后一個結點(最小權重)
}//遍歷
void Traverse(Tnode* N)
{int i = 0;if (N != NULL){Traverse(N->lchild);if (N->lchild == NULL && N->rchild == NULL)					//葉子結點{printf("%c結點權值:%d\t編碼:", N->data, N->frequency);for (i = 0; i < N->code_length; i++){cout << N->code[i];}cout << endl;}Traverse(N->rchild);}
}//初始化哈夫曼樹
void Init_hfmTree()
{hfmTree = (Tnode*)malloc(sizeof(Tnode));			//創(chuàng)建哈夫曼樹hfmTree->lchild = NULL;hfmTree->rchild = NULL;Pre = hfmTree;														//前一個結點
}//創(chuàng)建哈夫曼樹
Tnode Create_hfmTree()
{int len;Tnode* N = (Tnode*)malloc(sizeof(Tnode));while (N->frequency != sumFrequency){N = (Tnode*)malloc(sizeof(Tnode));N->lchild = (Tnode*)malloc(sizeof(Tnode));			//左孩子N->rchild = (Tnode*)malloc(sizeof(Tnode));			//右孩子if (length != -1)*N->lchild = Getmin();elseN->lchild = NULL;												//地址設為空if (length != -1)*N->rchild = Getmin();elseN->rchild = NULL;												//地址設為空N->data = '#';															//表示空N->frequency = N->lchild->frequency + N->rchild->frequency;		//求權重之和T[length++] = *N;													//放入數(shù)組}return *N;
}//結點編碼(初始存檔編碼)
void NodeEncode(Tnode* N)
{int i = 0;if (N != NULL){//向左走if (Pre->lchild == N){code[step++] = 0;				//向左走}else if (Pre->rchild == N){code[step++] = 1;				//向右走}Pre = N;									//保存上一結點if (N->lchild != NULL && N->rchild != NULL)		//未到達葉子結點{NodeEncode(N->lchild);step--;										//向回走Pre = N;									//保存上一結點NodeEncode(N->rchild);step--;										//向回走}else												//到達葉子結點{for (i = 0; i < step; i++)N->code[i] = code[i];			//記錄編碼N->code_length = step;			//記錄碼長}}
}//編碼
void Encode(Tnode* N)
{int i = 0;if (flag_exit)return;if (N != NULL && str[index_s] != '\0')				//到達葉子結點或者字符串到尾{if (N->lchild != NULL && N->rchild != NULL)		//未到達葉子結點{Encode(N->lchild);Encode(N->rchild);}else														//找到葉子結點{if (N->data == str_en[index_s])		//是要找的葉子結點{flag_exit = 1;							//退出標志for (i = 0; i < N->code_length; i++){sumCode[++index_c] = N->code[i];			//編碼存入}}}}
}//譯碼
void Decode(Tnode* N)
{int i = 0;if (N != NULL){if (N->lchild != NULL || N->rchild != NULL)					//沒有查找到葉子結點{if (code_de[index] == 0)			//向左走{index++;step++;Decode(N->lchild);step--;							//彈出來}else if (code_de[index] == 1)	//向右走{index++;step++;Decode(N->rchild);step--;							//彈出來}}else					//查找到葉子結點{cout << N->data;			//輸出譯碼結果}}
}int main()
{int choice;int i;Input();						//輸入字符GetFrequency();		//獲取字符串//葉子結點的創(chuàng)建與排序CreateTnode();			//創(chuàng)建樹節(jié)點//哈夫曼樹的初始化與創(chuàng)建Init_hfmTree();*hfmTree = Create_hfmTree();//結點編碼step = 0;NodeEncode(hfmTree);while (1){system("cls");cout << "請選擇需要的服務:\n";cout << "1、查找所有已保存的結點編碼和權\n";cout << "2、整體編碼\n";cout << "3、整體譯碼\n";cout << "0、退出\n";cout << "請選擇您需要的服務:\n";cin >> choice;//選項switch (choice){//0、退出case 0:exit(0);break;//1、遍歷所有葉子結點case 1:Traverse(hfmTree);				//查找所有編碼和權break;case 2:index_s = 0;Encode_Input();					//編碼輸入//逐字符編碼while (str_en[index_s] != '\0'){flag_exit = 0;Encode(hfmTree);index_s++;}Encode_Output();					//編碼輸出break;//3、譯碼case 3://輸入譯碼數(shù)組Decode_Input();index = 0;while (index < decode_length){//譯碼step = 0;Decode(hfmTree);			//譯碼并輸出}cout << endl;break;default:cout << "無此選項!" << endl;break;}system("pause");}return 0;
}

總結

以上是生活随笔為你收集整理的数据结构与算法(6-5)二叉树的应用--哈夫曼树与哈夫曼编码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久白浆| 日本韩国中文字幕 | 久久6精品 | 正在播放超嫩在线播放 | av一区二 | 欧美在线一区二区三区 | 不卡av在线播放 | 午夜影院在线看 | 大学生av | 久久国产乱 | 男人舔女人下部高潮全视频 | 伊人国产女 | 国产精品一级黄片 | 国产久久精品 | www.久久av | aaa天堂| 97视频网站 | 亚洲操图 | 欧美日韩一区二区三区在线电影 | 一区二区男女 | 日本黄色一区二区三区 | 用舌头去添高潮无码视频 | 韩国久久久 | 九色porny自拍视频 | av中文字幕免费观看 | 中字幕一区二区三区乱码 | 香蕉视频在线免费看 | 精品人妻少妇一区二区 | 风间由美av | 偷拍第一页 | 亚洲精品无人区 | 69亚洲乱人伦 | 亚洲精品乱码久久 | 肉丝美足丝袜一区二区三区四 | 在线免费观看日韩视频 | 亚洲永久精品一区二区 | 亚洲激情视频在线 | 无码人妻久久一区二区三区 | 亚洲最大视频网 | 欧美性生交大片免费看app麻豆 | 丝袜诱惑一区二区 | 国产98色在线 | 日韩 | 致命魔术电影高清在线观看 | 国产精品中文 | 亚洲青色在线 | 第四色成人网 | h视频在线看 | 欧美一区二区三区公司 | 亚洲欧洲中文 | 一区二区高清在线观看 | 秋霞成人网 | 欧美大黄 | 亚洲妇熟xx妇色黄蜜桃 | 橹图极品美女无圣光 | 久久入口| 三级网站免费观看 | 成年人网站免费 | 久久蜜桃av| 精品久久久久久久久久久久久久 | 一级免费在线观看 | 四虎在线播放 | 玩日本老头很兴奋xxxx | 超碰在线免费公开 | 夫の上司に犯波多野结衣853 | 欧美一区二区视频免费观看 | 欧美综合激情 | 91插插插影库永久免费 | 亚洲天堂社区 | 影音先锋中文字幕第一页 | 成人综合一区二区 | 日啪| 日韩最新中文字幕 | 欧美激情一区二区视频 | 先锋av在线资源 | 久久66热这里只有精品 | 逼逼av| 永久免费成人代码 | 欧美一区二区人人喊爽 | 女人一区二区三区 | 免费在线观看的av | 九九少妇 | 精品久久久久久久久久久久久久久 | www.三级| 精品韩国一区二区三区 | 国产成人无码久久久精品天美传媒 | 另类尿喷潮videofree | 国产高清二区 | 91啦丨九色丨刺激 | 深夜福利国产精品 | 亚洲第一色视频 | 亚洲高清精品视频 | 日韩激情小说 | 女人的洗澡毛片毛多 | 伊人中文字幕在线观看 | 全黄性性激高免费视频 | 国产一二区在线观看 | 97久久久 | 91精品国产闺蜜国产在线闺蜜 | a级免费网站 |