當前位置:編程學習大全網 - 源碼下載 - 創建壹個哈夫曼樹並且進行編碼權重如下w={5,29,7 8,14,13 ,3 ,11}寫出c語言代碼

創建壹個哈夫曼樹並且進行編碼權重如下w={5,29,7 8,14,13 ,3 ,11}寫出c語言代碼

#include?"stdafx.h"

#include?"hfm.h"

#include<string.h>

#include<malloc.h>?//malloc()等

#include<stdio.h>

#include<stdlib.h>

#include<ctype.h>

#include<limits.h>

#include<iostream>

#define?TRUE?1

#define?FALSE?1

#define?OK?1

#define?ERROR?1

#define?INFEASIBLE?-1

typedef?int?Status;

typedef?int?Boolean;

/************************************************************************/

/*?最優二叉樹簡稱:哈夫曼樹?*/

/************************************************************************/

//哈夫曼樹結構

;?typedef?struct{

unsigned?int?weight;?//權重

unsigned?int?parent,?lchild,?rchild;?//樹的雙親節點,和左右孩子

}HTNode,?*HuffmanTree;

typedef?char**?HuffmanCode;

//返回i個節點中權值最小的樹的根節點的序號,供select()調用

int?Min(HuffmanTree?T,?int?i){

int?j,?flag;

unsigned?int?k?=?UINT_MAX;?//%d-->UINT_MAX?=?-1,%u--->非常大的數

for?(j?=?1;?j?<=?i;?j++)

if?(T[j].weight?<?k?&&?T[j].parent?==?0)

k?=?T[j].weight,?flag?=?j;?//

T[flag].parent?=?1;//將parent標誌為1避免二次查找

return?flag;//返回

}

void?Select(HuffmanTree?T,?int?i,int&?s1,int&?s2){

//在i個節點中選取2個權值最小的樹的根節點序號,s1為序號較小的那個

int?j;

s1?=?Min(T,i);

s2?=?Min(T,i);

if?(s1?>?s2){

j?=?s1;

s1?=?s2;

s2?=?j;

}

}

//HuffmanCode代表的樹解碼二進制值

void?HuffmanCoding(HuffmanTree?&HT,?HuffmanCode&HC,?int*?w,?int?n){

//w存放n個字符的權值(均>0),構造哈夫曼樹HT,並求出n個字符的哈夫曼編碼HC

int?m,?i,?s1,?s2,?start;

unsigned?c,?f;

char*?cd;

//分配存儲空間

HuffmanTree?p;

if?(n?<=1)

return;

//n個字符(葉子節點)有2n-1個樹節點,所以樹節點m

m?=?2?*?n?-?1;

HT?=?(HuffmanTree)malloc((m?+?1)*sizeof(HTNode));?//0號元素未用

//這壹步是給哈夫曼樹的葉子節點初始化

for?(p?=?HT?+?1,?i?=?1;?i?<=?n;?++i,?++p,++w)

{

(*p).weight?=?*w;

(*p).lchild?=?0;

(*p).rchild?=?0;

(*p).parent?=?0;

}

//這壹步是給哈夫曼樹的非葉子節點初始化

for?(;?i?<=?m;?++i,?++p){

(*p).parent?=?0;

}

/************************************************************************/

/*?做完準備工作後?,開始建立哈夫曼樹

/************************************************************************/

for?(i?=?n?+?1;?i?<=?m;?i++)

{

//在HT[1~i-1]中選擇parent=0且weigh最小的節點,其序號分別為s1,s2

Select(HT,?i?-?1,?s1,?s2);?//傳引用

HT[s1].parent?=?HT[s2].parent=?i;

HT[i].lchild?=?s1;

HT[i].rchild?=?s2;

HT[i].weight?=?HT[s1].weight?+?HT[s2].weight;

}

/************************************************************************/

/*?從葉子到根逆求每個葉子節點的哈夫曼編碼?*/

/************************************************************************/

//分配n個字符編碼的頭指針向量,([0]不用)

HC?=?(HuffmanCode)malloc((n?+?1)*sizeof(char*));?

cd?=?(char*)malloc(n*sizeof(char));//分配求編碼的工作空間

cd[n?-?1]?=?'\0';?//結束符

for?(i?=?1;?i?<=?n;?i++)?//每個節點的遍歷

{

start?=?n?-?1;

for?(c?=?i,?f?=?HT[i].parent;?f?!=?0;?c?=?f,f?=?HT[f].parent){?//每個節點到根節點的遍歷

//從葉子節點到根節點的逆序編碼

if?(HT[f].lchild?==?c)

cd[--start]?=?'0';

else

cd[--start]?=?'1';

}

HC[i]?=?(char*)malloc((n?-?start)*sizeof(char));?//生成壹個塊內存存儲字符

//為第i個字符編碼分配空間

strcpy(HC[i],?&cd[start]);?//從cd賦值字符串到cd

}

free(cd);?//釋放資源

}

//函數聲明

int?Min(HuffmanTree?T,?int?i);?//求i個節點中的最小權重的序列號,並返回

void?Select(HuffmanTree?T,?int?i,?int&?s1,?int&?s2);?//從兩個最小權重中選取最小的(左邊)給s1,右邊的給s2

void?HuffmanCoding(HuffmanTree?&HT,?HuffmanCode&HC,?int*?w,?int?n);//哈夫曼編碼與解碼

int?main(){

HuffmanTree?HT;

HuffmanCode?HC;

int?*w,?n,?i;

printf("請輸入權值的個數(>1):");

scanf_s("%d",&n);

w?=?(int*)malloc(n*sizeof(int));

printf("請依次輸入%d個權值(整形):\n",n);

for?(i?=?0;?i?<=?n?-?1;i++)

{

scanf_s("%d",w+i);

}

HuffmanCoding(HT,?HC,?w,?n);

for?(i?=?1;?i?<=?n;i++)

{

puts(HC[i]);

}

return?0;

}

  • 上一篇:springboot 2.4.13 無法從nacos獲取配置,但是可以註冊到nacos
  • 下一篇:入侵基於JSP+Tomcat的Web網站實錄
  • copyright 2024編程學習大全網