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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

哈夫曼二叉树的构建

發(fā)布時(shí)間:2025/4/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哈夫曼二叉树的构建 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1 哈夫曼編碼
    • 2 哈夫曼二叉樹的構(gòu)建

1 哈夫曼編碼

哈夫曼(Huffman)編碼算法是基于二叉樹構(gòu)建編碼壓縮結(jié)構(gòu)的,它是數(shù)據(jù)壓縮中經(jīng)典的一種算法。算法根據(jù)文本字符出現(xiàn)的頻率,重新對(duì)字符進(jìn)行編碼。


哈夫曼編碼舉例: 假設(shè)要對(duì)“we will we will r u”進(jìn)行壓縮。




2 哈夫曼二叉樹的構(gòu)建











編碼實(shí)現(xiàn):
Huff.h:

#pragma once#include <stdio.h> #include <assert.h> #include <Windows.h> #include <iostream> #include <iomanip>using namespace std;#define MaxSize 1024 //隊(duì)列的最大容量typedef struct _Bnode {char value;int weight;struct _Bnode *parent;struct _Bnode *lchild;struct _Bnode *rchild; } Btree, Bnode; /* 結(jié)點(diǎn)結(jié)構(gòu)體 */typedef Bnode *DataType; //任務(wù)隊(duì)列中元素類型typedef struct _QNode { //結(jié)點(diǎn)結(jié)構(gòu)int priority; //每個(gè)節(jié)點(diǎn)的優(yōu)先級(jí),數(shù)值越大,優(yōu)先級(jí)越高,優(yōu)先級(jí)相同, 取第一個(gè)節(jié)點(diǎn)DataType data;struct _QNode *next; }QNode;typedef QNode * QueuePtr;typedef struct Queue {int length; //隊(duì)列的長度QueuePtr front; //隊(duì)頭指針QueuePtr rear; //隊(duì)尾指針 }LinkQueue;//隊(duì)列初始化,將隊(duì)列初始化為空隊(duì)列 void InitQueue(LinkQueue *LQ) {if(!LQ) return ;LQ->length = 0;LQ->front = LQ->rear = NULL; //把對(duì)頭和隊(duì)尾指針同時(shí)置 0 }//判斷隊(duì)列為空 int IsEmpty(LinkQueue *LQ) {if(!LQ) return 0;if (LQ->front == NULL){return 1;}return 0; }//判斷隊(duì)列是否為滿 int IsFull(LinkQueue *LQ) {if(!LQ) return 0;if (LQ->length == MaxSize){return 1;}return 0; }//入隊(duì),將元素 data 插入到隊(duì)列 LQ 中 int EnterQueue( LinkQueue *LQ,DataType data, int priority){if(!LQ) return 0;if(IsFull(LQ)){cout<<"無法插入元素 "<<data<<", 隊(duì)列已滿!"<<endl;return 0;}QNode *qNode = new QNode;qNode->data = data;qNode->priority = priority;qNode->next = NULL;if(IsEmpty(LQ)){//空隊(duì)列LQ->front = LQ->rear = qNode;}else {qNode->next = LQ->front;LQ->front = qNode;//LQ->rear->next =qNode;//在隊(duì)尾插入節(jié)點(diǎn) qNode//LQ->rear = qNode; //隊(duì)尾指向新插入的節(jié)點(diǎn)}LQ->length++;return 1; }//出隊(duì),遍歷隊(duì)列,找到隊(duì)列中優(yōu)先級(jí)最高的元素 data 出隊(duì) int PopQueue(LinkQueue *LQ, DataType *data){QNode **prev = NULL, *prev_node=NULL;//保存當(dāng)前已選舉的最高優(yōu)先級(jí)節(jié)點(diǎn)上一個(gè)節(jié)點(diǎn)的指針地址。QNode *last = NULL, *tmp = NULL;if(!LQ || IsEmpty(LQ)){cout<<"隊(duì)列為空!"<<endl;return 0;}if(!data) return 0;//prev 指向隊(duì)頭 front 指針的地址prev = &(LQ->front);//printf("第一個(gè)節(jié)點(diǎn)的優(yōu)先級(jí): %d\n", (*prev)->priority);last = LQ->front;tmp = last->next;while(tmp){if(tmp->priority <(*prev)->priority){//printf("抓到個(gè)更小優(yōu)先級(jí)的節(jié)點(diǎn)[priority: %d]\n",tmp->priority);prev = &(last->next);prev_node= last;}last=tmp;tmp=tmp->next;}*data = (*prev)->data;tmp = *prev;*prev = (*prev)->next;delete tmp;LQ->length--;//接下來存在 2 種情況需要分別對(duì)待//1.刪除的是首節(jié)點(diǎn),而且隊(duì)列長度為零if(LQ->length==0){LQ->rear=NULL;}//2.刪除的是尾部節(jié)點(diǎn)if(prev_node&&prev_node->next==NULL){LQ->rear=prev_node;}return 1; }//打印隊(duì)列中的各元素 void PrintQueue(LinkQueue *LQ) { QueuePtr tmp;if(!LQ) return ;if(LQ->front==NULL){cout<<"隊(duì)列為空!";return ;}tmp = LQ->front;while(tmp){cout<<setw(4)<<tmp->data->value<<"["<<tmp->priority<<"]";tmp = tmp->next;}cout<<endl; }//獲取隊(duì)首元素,不出隊(duì) int GetHead(LinkQueue *LQ,DataType *data) {if (!LQ || IsEmpty(LQ)){cout<<"隊(duì)列為空!"<<endl;return 0;}if(!data) return 0;*data = LQ->front->data;return 1; }//清空隊(duì)列 void ClearQueue(LinkQueue *LQ) {if(!LQ) return ;while(LQ->front){QueuePtr tmp = LQ->front->next;delete LQ->front;LQ->front = tmp;}LQ->front = LQ->rear = NULL;LQ->length = 0; }//獲取隊(duì)列中元素的個(gè)數(shù) int getLength(LinkQueue* LQ){if(!LQ) return 0;return LQ->length; }

哈夫曼編碼實(shí)現(xiàn).cpp:

#include <stdio.h> #include <stdlib.h> #include <iostream> #include "Huff.h"using namespace std; void PreOrderRec(Btree *root);/* 構(gòu)造哈夫曼編碼樹 */ void HuffmanTree (Btree * &huff, int n) {LinkQueue *LQ = new LinkQueue;int i = 0;//初始化隊(duì)列InitQueue(LQ);/* 初始化存放哈夫曼樹數(shù)組 HuffNode[] 中的結(jié)點(diǎn) */for (i=0; i<n; i++){Bnode * node = new Bnode;cout<<"請(qǐng)輸入第"<<i+1<<"個(gè)字符和出現(xiàn)頻率: "<<endl;cin>>node->value; //輸入字符cin>>node->weight ;//輸入權(quán)值node->parent =NULL;node->lchild =NULL;node->rchild =NULL;EnterQueue(LQ, node, node->weight);}PrintQueue(LQ);//system("pause");//exit(0);do{Bnode *node1 = NULL;Bnode *node2 = NULL;if(!IsEmpty(LQ)){PopQueue(LQ, &node1);printf("第一個(gè)出隊(duì)列的數(shù):%c, 優(yōu)先級(jí): %d\n", node1->value,node1->weight);}else {break;}if(!IsEmpty(LQ)){Bnode *node3 = new Bnode;PopQueue(LQ, &node2);printf("第二個(gè)出隊(duì)列的數(shù):%c, 優(yōu)先級(jí): %d\n", node2->value,node2->weight);node3->lchild = node1;node1->parent = node3;node3->rchild = node2;node2->parent = node3;node3->value = ' ';node3->weight=node1->weight+node2->weight;printf("合并進(jìn)隊(duì)列的數(shù):%c, 優(yōu)先級(jí): %d\n", node3->value,node3->weight);EnterQueue(LQ,node3, node3->weight);}else {huff = node1;break;}}while(1); } /************************ * 采用遞歸方式實(shí)現(xiàn)前序遍歷 *************************/ void PreOrderRec(Btree *root) {if (root == NULL){return;}printf("- %c -", root->value);PreOrderRec(root->lchild);PreOrderRec(root->rchild); }int main(void){Btree * tree = NULL;HuffmanTree(tree, 7);PreOrderRec(tree);system("pause");return 0; }

參考資料:

  • C/C++從入門到精通-高級(jí)程序員之路【奇牛學(xué)院】
  • 《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的哈夫曼二叉树的构建的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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