導航:首頁 > 源碼編譯 > 哈夫曼樹編譯器程序代碼

哈夫曼樹編譯器程序代碼

發布時間:2022-08-06 16:07:12

❶ 哈夫曼樹c++程序代碼

#include <iostream>
#include <stdlib.h>using namespace std;
const int MaxValue = 10000; //初始設定的權值最大值
const int MaxBit = 4; //初始設定的最大編碼位數
const int MaxN = 10; //初始設定的最大結點個數
struct HaffNode //哈夫曼樹的結點結構
{
int weight; //權值
int flag; //標記
int parent; //雙親結點下標
int leftChild; //左孩子下標
int rightChild; //右孩子下標
};
struct Code //存放哈夫曼編碼的數據元素結構
{
int bit[MaxN]; //數組
int start; //編碼的起始下標
int weight; //字元的權值
};
void Haffman(int weight[], int n, HaffNode haffTree[])
//建立葉結點個數為n權值為weight的哈夫曼樹haffTree
{
int j, m1, m2, x1, x2;
//哈夫曼樹haffTree初始化。n個葉結點的哈夫曼樹共有2n-1個結點
for(int i = 0; i < 2 * n - 1 ; i++) {
if(i < n) haffTree[i].weight = weight[i];
else haffTree[i].weight = 0;
haffTree[i].parent = 0;
haffTree[i].flag = 0;
haffTree[i].leftChild = -1;
haffTree[i].rightChild = -1;
}
//構造哈夫曼樹haffTree的n-1個非葉結點
for(i = 0;i < n-1;i++) {
m1 = m2 = MaxValue;
x1 = x2 = 0;
for(j = 0; j < n+i;j++) {
if (haffTree[j].weight < m1 && haffTree[j].flag == 0){
m2 = m1;
x2 = x1;
m1 = haffTree[j].weight;
x1 = j;
}
else if(haffTree[j].weight < m2 && haffTree[j].flag == 0){
m2 = haffTree[j].weight;
x2 = j;
}
}
//將找出的兩棵權值最小的子樹合並為一棵子樹
haffTree[x1].parent = n+i;
haffTree[x2].parent = n+i;
haffTree[x1].flag = 1;
haffTree[x2].flag = 1;
haffTree[n+i].weight = haffTree[x1].weight+haffTree[x2].weight;
haffTree[n+i].leftChild = x1;
haffTree[n+i].rightChild = x2;
}
}
void HaffmanCode(HaffNode haffTree[], int n, Code haffCode[])
//由n個結點的哈夫曼樹haffTree構造哈夫曼編碼haffCode
{
Code *cd = new Code;
int child, parent;
//求n個葉結點的哈夫曼編碼
for(int i = 0; i < n; i++) {
cd->start = n-1; //不等長編碼的最後一位為n-1
cd->weight = haffTree[i].weight; //取得編碼對應權值的字元
child = i;
parent = haffTree[child].parent;
//由葉結點向上直到根結點
while(parent != 0)
{
if(haffTree[parent].leftChild == child)
cd->bit[cd->start] = 0; //左孩子結點編碼0
else
cd->bit[cd->start] = 1;//右孩子結點編碼1
cd->start--;
child = parent;
parent = haffTree[child].parent;
}
//保存葉結點的編碼和不等長編碼的起始位
for(int j = cd->start+1; j < n; j++)
haffCode[i].bit[j] = cd->bit[j];
haffCode[i].start = cd->start;
haffCode[i].weight = cd->weight; //保存編碼對應的權值
}
}
void main(void){
int i, j, n = 4;
int weight[] = {1,3,5,7};
HaffNode *myHaffTree = new HaffNode[2*n+1];
Code *myHaffCode = new Code[n];
if(n > MaxN) {
cout << "定義的n越界,修改MaxN! " << endl;
exit(0);
}
Haffman(weight, n, myHaffTree);
HaffmanCode(myHaffTree, n, myHaffCode);
//輸出每個葉結點的哈夫曼編碼
for(i = 0; i < n; i++) {
cout << "Weight = " << myHaffCode[i].weight << " Code = ";
for(j = myHaffCode[i].start+1; j < n; j++)
cout << myHaffCode[i].bit[j];
cout << endl;
}
}

❷ 求哈夫曼編譯器 C語言代碼

// huffman.cpp : Defines the entry point for the console application.
//

#include <iostream.h>
#include <stdio.h>
#include <string.h>
const long wordnum = 1000;//最大不同單詞數
const long code_len = wordnum/10;
const long wordlen = 30;//單詞最長長度
const long codemax = 10000;//最大haffuman編碼長度
const long wordmax = 10000;//最大單詞數
//str類定義
class str
{
public:
str();
bool operator<(str obj);//運算符重載方便對str的排序使用二分搜索模板
bool operator>(str obj);
str operator=(char p[]);
str operator++(int);//重載後綴方式的++
char *getword();
long getfre();
protected:
private:
char word[wordlen];
long frequence;
};
str::str()
{
frequence = 0;
}
//以下為重載str類中的運算符
bool str::operator<(str obj)
{
if(strcmp(word,obj.word) < 0)
return true;
else
return false;
}
bool str::operator>(str obj)
{
if(strcmp(word,obj.word) > 0)
return true;
else
return false;
}
str str::operator=(char p[])
{
strcpy(word,p);
return *this;
}
str str::operator++(int x)
{
frequence ++;
return *this;
}
char * str::getword()
{
return word;
}
long str::getfre()
{
return frequence;
}
//str類定義結束

//Node類定義
class Node
{
public:
Node();
bool operator<(Node obj);//運算符重載方便對Node的排序使用堆模板
bool operator<=(Node obj);
bool operator>(Node obj);
Node operator=(str obj);
Node operator+(Node &obj);
Node *leftp();//類外獲取指向當前節點的孩子的指針
Node *rightp();
char *getword(Node *p);//類外獲取節點信息
long getfrequence();
protected:
private:
char word[wordlen];
long frequence;
Node *left, *right;
};

Node::Node()
{
strcpy(word,"NULL");
left = NULL;
right = NULL;
}
//以下為重載Node類中的運算符
bool Node::operator<(Node obj)
{
if(frequence < obj.frequence)
return true;
else
return false;
}
bool Node::operator<=(Node obj)
{
if(frequence <= obj.frequence)
return true;
else
return false;
}
bool Node::operator>(Node obj)
{
if(frequence > obj.frequence)
return true;
else
return false;
}
Node Node::operator+(Node &obj)
{
Node sum;
sum.frequence = frequence + obj.frequence;//指針指向了NULL
sum.left = this;
sum.right = &obj;
return sum;
}
Node Node::operator=(str obj)
{
strcpy(word,obj.getword());
frequence = obj.getfre();
return *this;
}
Node * Node::leftp()
{
return left;
}
Node * Node::rightp()
{
return right;
}
char * Node::getword(Node *p)
{
return p->word;
}
long Node::getfrequence()
{
return frequence;
}
//Node類定義結束

//str類專門用於統計詞頻使用,Node則用於構造huffman樹,由於兩者使用的key不同,前者是word的字典序
//後者是詞頻,於是使用了兩個類來實現。

class huffman
{
public:
huffman();
template<typename entry>
friend bool binarysearch(entry list[wordnum],entry target,long bottom,long top,long &position);
template<typename entry>
friend void buidheap(entry a[wordnum], long number);
template<typename entry>
friend void heapify(entry a[wordnum], long high, long low);
template<typename entry>
friend void swap(entry a[wordnum], long i, long j);
bool Stat();
void Encode();
bool Decode(char code[]);
Node update(long end);
void proce_code();
void Inorder(Node *current, char currentcode[], long &num);
protected:
private:
Node SortedNode[wordnum];//從中產生huffman樹
char NodeCode[wordnum][wordnum/10];//相應編碼
Node root;
bool sign;//用於標記是否已經建立了huffman樹
long n;//葉子節點個數
};
huffman::huffman()
{
sign = false;
}

//二分用於統計詞頻
template<typename entry>
bool binarysearch(entry list[wordnum], entry target, long bottom, long top, long &position)
{
while(bottom <= top)
{
position = (bottom + top)/2;
if(list[position] < target)
bottom = position + 1;
else if(list[position] > target)
top = position - 1;
else
return true;
}
return false;
}

//建立最小堆及調整為最小堆
template<typename entry>
void swap(entry a[wordnum], long i, long j)
{
entry s;
s = a[i];
a[i] = a[j];
a[j] = s;
}

template<typename entry>
void buidheap(entry a[wordnum], long number)
{
long i ,j;
for(i = number/2; i >= 1; i--)
{
j = i;
while(j <= number/2)
{
if(a[j] > a[2*j] || (a[j] > a[2*j + 1] && 2*j + 1 <= number))
{
if(a[2*j] > a[2*j + 1] && 2*j + 1 <= number)
{
swap(a, j, 2*j+1);
j = 2*j + 1;
}
else
{
swap(a, j ,2*j);
j = 2*j;
}
}
else
break;
}
}
}

template<typename entry>
void heapify(entry a[wordnum], long high, long low)
{
long j = low;
while(j <= high/2)
{
if(a[j] > a[2*j] && a[j] > a[2*j + 1])
{
if(a[2*j] > a[2*j + 1] && 2*j + 1 <= high)
{
swap(a, j, 2*j+1);
j = 2*j + 1;
}
else if(2*j <= high)
{
swap(a, j, 2*j);
j = 2*j;
}
}
else if(a[j] <= a[2*j] && a[j] > a[2*j + 1] && 2*j + 1 <= high)
{
swap(a, j, 2*j+1);
j = 2*j + 1;
}
else if(a[j] <= a[2*j + 1] && a[j] > a[2*j] && 2*j <= high)
{
swap(a, j, 2*j);
j = 2*j;
}
else
break;
}
}
//詞頻統計函數Stat()
bool huffman::Stat()
{
long i,position;
char p[wordmax],*get;
str s[wordnum],current;
n = 0;
while(gets(p) != NULL && strcmp(p,"@") != 0)
{
get = strtok(p," ,.!/-:;?");
while(get != NULL)
{
current = get;
if(binarysearch(s,current,0,n,position) == true && n < wordnum - 1)
s[position] ++;
else
{
n ++;
if(n < wordnum - 1)
{
if(s[position] < current && current.getfre() < s[position].getfre())
position ++;
for(i = n; i >= position; i --)
s[i+1] = s[i];
s[position] = current;
s[position] ++;
}
}
get = strtok(NULL," ,.!/-:;?");
}
}
for(i = 1; i <= n && i < wordnum; i ++)
SortedNode[i] = s[i-1];
if(n < wordnum)
return true;
else
{
n = wordnum - 1;
return false;
}
}

//建立huffman樹函數
void huffman::Encode()
{
int i;
sign = true;
buidheap(SortedNode,n);
for(i = 1; i < n; i ++)
root = update(n-i+1);
}

Node huffman::update(long end)
{
Node *p,*q;
Node newNode;
p = new Node;
q = new Node;
*p = SortedNode[1];
swap(SortedNode,1,end);
heapify(SortedNode,end-1,1);//取出了一個最小元,然後將堆進行了調整
*q = SortedNode[1];
newNode = *p + *q;
SortedNode[1] = newNode;
heapify(SortedNode,end-1,1);//又取出最小元,並且把新節點賦為SortedNode[1],調整了堆
return SortedNode[1];
}

//解碼函數
bool huffman::Decode(char code[codemax])
{
int i;
Node *find = &root;
Node *l = NULL,*r = NULL;
bool flag = true;
if(sign == true)
{
for(i = 0; code[i] != '\0' && flag == true; i ++)
{
l = find->leftp();
r = find->rightp();
if(code[i] == '0' && l != NULL)
find = l;
else if(code[i] == '1' && r != NULL)
find = r;
else flag = false;
if(find->leftp() == NULL && find->rightp() == NULL)
{
printf("%s ",find->getword(find));
find = &root;
}
}
if(!((find->leftp() == NULL && find->rightp() == NULL) || find == &root))
{
cout << "There are some wrong codes in th input!" << endl;
flag = false;
}
}
else
flag = false;
return flag;
}
void huffman::Inorder(Node *current, char currentcode[], long &num)
{
Node *l, *r;
char cl[code_len], cr[code_len];
if(current != NULL)
{
l = current->leftp();
r = current->rightp();
strcpy(cl,currentcode);
strcat(cl,"0");
strcpy(cr,currentcode);
strcat(cr,"1");
Inorder(l, cl, num);
if(l == NULL && r == NULL)
{
SortedNode[num] = *current;
strcpy(NodeCode[num],currentcode);
num ++;
}
Inorder(r, cr, num);
}
}
void huffman::proce_code()//利用中序遍歷來得到相應的編碼
{
char current[code_len] = "";
long num = 1;
Inorder(&root, current,num);
for(long i = 1; i <= n; i ++)
{
cout << SortedNode[i].getword(&SortedNode[i]) << "----" << NodeCode[i]<<" " ;
if(i%3 == 0) cout << endl;
}
}

int main()
{
huffman test;
char code[codemax];
char order;
cout << "顯示編碼(Show)" << " "<< "解碼(Decode)" << " " <<"退出(Quit)" << endl;
cout << "Input the passage, to end with a single @ in a single line:" << endl;
test.Stat();
test.Encode();
cout << "Encoded!" << endl;
while(cin >> order)
{
if(order == 's' || order == 'S')
{
test.proce_code();
cout << "Proced!" << endl;
}
else if(order == 'd' || order == 'D')
{
cout << "Input the codes:" << endl;
cin >> code;
while(test.Decode(code))
cin >> code;
}
else if(order == 'q' || order == 'Q')
break;
}
return 0;
}

❸ 急求關於生成哈夫曼樹的程序代碼~謝謝啦!

#include<iostream>
using namespace std;

typedef struct {
int weight;
int parent;
int lchild;
int rchild;
}HTreeNode,*HTree;

void createHTree(HTree *t ,int * w, int n ){
void select(HTree t, int i, int *s1, int *s2);
*t = new HTreeNode[2*n-1];
for(int i=0;i<n;i++){
(*t)[i].weight = w[i];
(*t)[i].parent = 0;
(*t)[i].lchild = 0;
(*t)[i].rchild = 0;
}
for(int i=n;i<2*n-1;i++){
(*t)[i].weight = 0;
(*t)[i].parent = 0;
(*t)[i].lchild = 0;
(*t)[i].rchild = 0;
}

int s1,s2;
for(int i=n;i<2*n-1;i++){
select (*t, i,&s1,&s2);
(*t)[i].weight=(*t)[s1].weight+(*t)[s2].weight;
(*t)[i].lchild = s1;
(*t)[i].rchild = s2;
(*t)[s1].parent = i;
(*t)[s2].parent = i;
}

for(int i=0;i<2*n-1;i++){
printf("%-3d%4d%4d%4d%4d\n",i,(*t)[i].weight,(*t)[i].parent,(*t)[i].lchild,(*t)[i].rchild);
}

}

void select(HTree t, int i, int *s1, int *s2){
for(int j=0;j<i;j++){
if(t[j].parent==0){*s1=j; break;}
}
for(int j=*s1;j<i;j++){
if( t[j].parent==0 && t[j].weight<t[*s1].weight ){
*s1 = j;
}
}/////////////////////////////////////////
for(int j=0;j<i;j++){
if(t[j].parent==0 && j!=*s1){*s2=j; break;}
}
for(int j=*s2;j<i;j++){
if(t[j].parent==0 && t[j].weight<t[*s2].weight && j!=*s1){
*s2 = j;
}
}
int temp;
if(*s1>*s2){
temp = *s1;
*s1= *s2;
*s2=temp;
}
}

void encode(HTree t, int n){
int temp,temp2;
string s = "";
for(int i = 0 ;i<n;i++){
printf("weight: %-4d",t[i].weight);
temp = i;
s="";
while(t[temp].parent !=0){
temp2 = temp;
temp = t[temp].parent;
if(t[temp].lchild == temp2) s.append("0");
if(t[temp].rchild == temp2) s.append("1");
}
string::reverse_iterator it = s.rbegin();
while(it != s.rend()){
cout<<*it;
it++;
}
cout<<endl;
}
}

int main(){
int w[5] ={4,7,5,2,9};
int n = 5;
HTree t = NULL;
createHTree( &t,w,n);
cout<<endl;
encode(t,n);
system("PAUSE");
}

❹ C語言程序設計 ! 關於哈夫曼樹編譯器

哈夫曼樹

#include<stdio.h>

#include<stdlib.h>

#define n 8

struct nodeinfo

{

char
ch; //節點值

int weight; //權值

}node[n];

struct hafftab //哈夫曼樹

{

int w;

int parent;

int leftc;

int rightc;

}ht[2*n-1];

void initial() //初始化哈夫曼樹

{

int i;

for(i=0;i<n;i++)

{

fflush(stdin);

scanf("%c%d",&node[i].ch,&node[i].weight);

ht[i].w=node[i].weight;

ht[i].leftc= ht[i].parent=ht[i].rightc=-1;

}

return
;

}

void creathafftable() //構造哈夫曼樹

{

int i,j;

int min1,min2; //存放最小下標

for(i=n;i<2*n-1;i++)

{

min1=min2=-1;

for(j=0;j<i;j++)

{

if(ht[j].parent!=-1)

continue;

else

{

if(min1==-1)

{

min1=j;

continue;

}

if(min2==-1)

{

if(ht[j].w<ht[min1].w)

{

min2=min1;

min1=j;

}

else

min2=j;

continue;

}

if(ht[j].w<ht[min1].w)

{

min2=min1;

min1=j;

}

else

{

if(ht[j].w<ht[min2].w)

min2=j;

}

}

}

ht[i].w=ht[min1].w+ht[min2].w;

ht[i].parent=-1;

ht[i].leftc=min1;

ht[i].rightc=min2;

ht[min1].parent=ht[min2].parent=i;

}

}

void disp()

{

int
i;

printf("index--weight--parent--leftc--rightc--\n");

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

printf("--%4d %4d %4d %4d %4d--\n",i,ht[i].w,ht[i].parent,ht[i].leftc,ht[i].rightc);

return;

}

void Encode() //編碼

{

int
i,stack[20],top,pt;

for(i=0;i<n;i++)

{

top
= -1;pt = i; //i表示要編碼的元素

while(
ht[pt].parent >= 0)

{

if(pt
== ht[ht[pt].parent].leftc )

{
top++; stack[top] = 0;}

else

{ top++; stack[top] = 1;}

pt
= ht[pt].parent;

}

printf("%2c's
encode:",node[i].ch);

while(
top>=0)

{

printf("%d",stack[top]);

top--;

}printf("\n");

}

}

void Decode(char code[]) //解碼

{

char
*p;int i;

p
= code;

while(
*p !='\0' )

{

i=2*n-2;

while(1)

{

if(
*p == '1')

{

i
= ht[i].rightc;

}

else

{

i
= ht[i].leftc;

}

if(ht[i].leftc==-1
|| ht[i].rightc==-1)

{

printf("%c",node[i].ch);

p++;

break;

}

else

{

p++;

}

}

}

printf("\n");

}

void main()

{

char code[100];

initial();

creathafftable();

disp();

Encode();

printf("input
code:\n");

scanf("%s",code);

Decode(code);

}
根據自己的要求稍微改下就可以了

❺ 怎麼樣用c語言程序編碼哈夫曼樹

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <ctype.h>
#include<limits.h>
int function1(char ch,char *s)
{
int i;
for(i=0; s[i]!='\0'; i++)
{
if(ch==s[i])return 0;
}
return 1;
}
typedef struct
{
unsigned int weight;
unsigned int parent,lchild,rchild;
} HTNode,*HuffmanTree; // 動態分配數組存儲赫夫曼樹
typedef char **HuffmanCode; // 動態分配數組存儲赫夫曼編碼表
// algo6-1.cpp 求赫夫曼編碼。實現演算法6.12的程序

int min(HuffmanTree t,int i)
{
// 函數void select()調用
int j,flag;
unsigned int k=UINT_MAX; // 取k為不小於可能的值
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;
return flag;
}

void select(HuffmanTree t,int i,int &s1,int &s2)
{
// s1為最小的兩個值中序號小的那個

s1=min(t,i);
s2=min(t,i);
/* if(s1>s2)
{
j=s1;
s1=s2;
s2=j;
}*/
}

void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n) // 演算法6.12
{
// w存放n個字元的權值(均>0),構造赫夫曼樹HT,並求出n個字元的赫夫曼編碼HC
int m,i,s1,s2,start;
unsigned c,f;
HuffmanTree p;
char *cd;
if(n<=1)
return;
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).parent=0;
(*p).lchild=0;
(*p).rchild=0;
}
for(; i<=m; ++i,++p)
(*p).parent=0;
for(i=n+1; i<=m; ++i) // 建赫夫曼樹
{
// 在HT[1~i-1]中選擇parent為0且weight最小的兩個結點,其序號分別為s1和s2
select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].rchild=s1;
HT[i].lchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
// printf("HT[%d].lchild:%d HT[%d].rchild:%d\n",i,s2,i,s1);
}
// 從葉子到根逆向求每個字元的赫夫曼編碼
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
// 分配n個字元編碼的頭指針向量([0]不用)
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]='1';
else
cd[--start]='0';
HC[i]=(char*)malloc((n-start)*sizeof(char));
// 為第i個字元編碼分配空間
strcpy(HC[i],&cd[start]); // 從cd復制編碼(串)到HC
}
free(cd); // 釋放工作空間
}
void swap1(int *a ,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
void swap2(char *a,char *b)
{
char ch;
ch=*a;
*a=*b;
*b=ch;
}
int main(void)
{
HuffmanTree HT;
HuffmanCode HC;
char *s1,*s2;
int i,j=0,n,count,*m,t,flag=1;
scanf("%d",&n);
getchar();
s1=(char*)malloc((n+n)*sizeof(char));
s2=(char*)malloc(n*sizeof(char));
memset(s2,'\0',n*sizeof(char));
gets(s1);
count=strlen(s1);
for(i=0; i<count; i++)
{
if(!isspace(*(s1+i)))
{
if(function1(*(s1+i),s2))
{
*(s2+j)=*(s1+i);
j++;
}
}
else;
}
m=(int*)malloc(j*sizeof(int));
for(i=0; i<j; i++)
*(m+i)=0;
for(t=0; t<j; t++)
{
for(i=0; i<count; i++)
{
if(*(s2+t)==*(s1+i))
*(m+t)+=1;
}
}
for(i=0;i<j;i++)
while(flag)
{
flag = 0;
for (t=0; t<j-1; t++)
{
if(*(m+t)<*(m+t+1))
{
swap1(m+t,m+t+1);
swap2(s2+t,s2+t+1);
flag=1;
}
}
}
HuffmanCoding(HT,HC,m,j);
for(i=1,t=0; i<=j; i++,t++)
{
printf("%c %d %s\n",*(s2+t),*(m+t),HC[i]);

}
return 0;
}

❻ 編寫一個程序,構造一棵哈夫曼樹

#include<stdio.h>
#include<string.h>
#define N 50 //葉子結點數
#define M 2*N-1 //樹中結點總數
typedef struct
{ char data[5]; //節點值
int weight; //權重
int parent; //雙親結點
int lchild; //左孩子結點
int rchild; //右孩子結點
}htnode;
typedef struct
{ char cd[N]; //存放哈夫曼碼
int start;
}hcode;
void createht(htnode ht[],int n) //構造哈夫曼樹
{ int i,k,lnode,rnode;
int min1,min2;
for(i=0;i<2*n-1;i++) //所有結點的相關域置初值-1
ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
for(i=n;i<2*n-1;i++) //構造哈夫曼樹
{ min1=min2=32767; //lchild和rchild為最小權重的兩個結點位置
lnode=rnode=-1;
for(k=0;k<=i-1;k++)
if(ht[k].parent==-1) //只在尚未構造二叉樹的結點中查找
{ if(ht[k].weight<min1)
{ min2=min1;
rnode=lnode;
min1=ht[k].weight;
lnode=k;
}
else if(ht[k].weight<min2)
{ min2=ht[k].weight;
rnode=k;
}
}
ht[lnode].parent=i;
ht[rnode].parent=i;
ht[i].weight=ht[lnode].weight+ht[rnode].weight;
ht[i].lchild=lnode;
ht[i].rchild=rnode;
}
}
void createhcode(htnode ht[],hcode hcd[],int n) //構造哈夫曼編碼
{ int i,f,c;
hcode hc;
for(i=0;i<n;i++) //根據哈夫曼樹求哈夫曼編碼
{ hc.start=n;
c=i;
f=ht[i].parent;
while(f!=-1) //循序直到樹根結點
{ if(ht[f].lchild==c) //處理左孩子結點
hc.cd[hc.start--]='0';
else
hc.cd[hc.start--]='1'; //處理右孩子結點
c=f;
f=ht[f].parent;
}
hc.start++; //start指向哈夫曼編碼最開始字元
hcd[i]=hc;
}
}
void disphcode(htnode ht[],hcode hcd[],int n) // 輸出哈夫曼編碼
{ int i,k;
int sum=0,m=0,j;
printf("輸出哈夫曼編碼:\n");
for(i=0;i<n;i++)
{ j=0;
printf(" %s:\t",ht[i].data);
for(k=hcd[i].start;k<=n;k++)
{ printf("%c",hcd[i].cd[k]);
j++;
}
m+=ht[i].weight;
sum+=ht[i].weight*j;
printf("\n");
}
printf("\n平均長度=%g\n",1.0*sum/m);
}
void main()
{ int n=15,i;
char *str[]={"The","of","a","to","and","in","that","he","is","at","on","for","His","are","be"};
int fnum[]={1192,677,541,518,462,450,242,195,190,181,174,157,138,124,123};
htnode ht[M];
hcode hcd[N];
for(i=0;i<n;i++)
{ strcpy(ht[i].data,str[i]);
ht[i].weight=fnum[i];
}
printf("\n");
createht(ht,n);
createhcode(ht,hcd,n);
disphcode(ht,hcd,n);
printf("\n");
}

❼ 哈夫曼樹及哈夫曼編碼的C程序實現(數據結構題)

去年做的課程設計,有什麼不合要求的自己改改

#include<string.h>
#include<stdlib.h>
#include<stdio.h>

int m,s1,s2;

typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //動態分配數組存儲哈夫曼樹
typedef char *HuffmanCode; //動態分配數組存儲哈夫曼編碼表

void Select(HuffmanTree HT,int n) {
int i,j;
for(i = 1;i <= n;i++)
if(!HT[i].parent){s1 = i;break;}
for(j = i+1;j <= n;j++)
if(!HT[j].parent){s2 = j;break;}
for(i = 1;i <= n;i++)
if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i))s1=i;
for(j = 1;j <= n;j++)
if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j))s2=j;
}

void HuffmanCoding(HuffmanTree &HT, HuffmanCode HC[], int *w, int n) {
// 演算法6.13
// w存放n個字元的權值(均>0),構造哈夫曼樹HT,
// 並求出n個字元的哈夫曼編碼HC
int i, j;
char *cd;
int p;
int cdlen;

if (n<=1) return;
m = 2 * n - 1;
HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0號單元未用
for (i=1; i<=n; i++) { //初始化
HT[i].weight=w[i-1];
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for (i=n+1; i<=m; i++) { //初始化
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
puts("\n哈夫曼樹的構造過程如下所示:");
printf("HT初態:\n 結點 weight parent lchild rchild");
for (i=1; i<=m; i++)
printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight,
HT[i].parent,HT[i].lchild, HT[i].rchild);
printf(" 按任意鍵,繼續 ...");
getchar();
for (i=n+1; i<=m; i++) { // 建哈夫曼樹
// 在HT[1..i-1]中選擇parent為0且weight最小的兩個結點,
// 其序號分別為s1和s2。
Select(HT, i-1);
HT[s1].parent = i; HT[s2].parent = i;
HT[i].lchild = s1; HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
printf("\nselect: s1=%d s2=%d\n", s1, s2);
printf(" 結點 weight parent lchild rchild");
for (j=1; j<=i; j++)
printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,
HT[j].parent,HT[j].lchild, HT[j].rchild);
printf(" 按任意鍵,繼續 ...");
getchar();
}

//------無棧非遞歸遍歷哈夫曼樹,求哈夫曼編碼
cd = (char *)malloc(n*sizeof(char)); // 分配求編碼的工作空間
p = m; cdlen = 0;
for (i=1; i<=m; ++i) // 遍歷哈夫曼樹時用作結點狀態標志
HT[i].weight = 0;
while (p) {
if (HT[p].weight==0) { // 向左
HT[p].weight = 1;
if (HT[p].lchild != 0) { p = HT[p].lchild; cd[cdlen++] ='0'; }
else if (HT[p].rchild == 0) { // 登記葉子結點的字元的編碼
HC[p] = (char *)malloc((cdlen+1) * sizeof(char));
cd[cdlen] ='\0'; strcpy(HC[p], cd); // 復制編碼(串)
}
} else if (HT[p].weight==1) { // 向右
HT[p].weight = 2;
if (HT[p].rchild != 0) { p = HT[p].rchild; cd[cdlen++] ='1'; }
} else { // HT[p].weight==2,退回退到父結點,編碼長度減1
HT[p].weight = 0; p = HT[p].parent; --cdlen;
}
}
} // HuffmanCoding
void main() {
HuffmanTree HT;HuffmanCode *HC;int *w,n,i;
puts("輸入結點數:");
scanf("%d",&n);
HC = (HuffmanCode *)malloc(n*sizeof(HuffmanCode));
w = (int *)malloc(n*sizeof(int));
printf("輸入%d個結點的權值\n",n);
for(i = 0;i < n;i++)
scanf("%d",&w[i]);
HuffmanCoding(HT,HC,w,n);
puts("\n各結點的哈夫曼編碼:");
for(i = 1;i <= n;i++)
printf("%2d(%4d):%s\n",i,w[i-1],HC[i]);
getchar();
}

❽ 急球C++數據結構 哈夫曼編譯程序代碼

# include<stdio.h>
#include<stdlib.h>
#define MAXLEN 100

typedef struct Huffmantree {
char ch; /*鍵值*/

int weight,mark; /*weight為權值,mark為標志域*/
struct Huffmantree *parent,*lchild,*rchild,*next;
}Hftree,*linktree;

/*整理輸入的字元串,合並相同的項,並求出每個字元在數組中出現的次數 */
linktree tidycharacter(char character[])
{
int i=0;
linktree tree,ptr,beforeptr,node; /*鏈式 ,tree為頭結點,beforeptr為ptr的前一結點,node為新申請的結點*/

tree=(linktree)malloc(sizeof(Hftree));/*創建單鏈表的頭結點*/
if(!tree)return NULL;
tree->next=NULL; /* 頭結點為空,且後續結點為空*/

for(i=0;character[i]!='\0'&&character[i]!='\n';i++) { /*遍歷直到字元串結束為止*/
ptr=tree;
beforeptr=tree;

node=(linktree)malloc(sizeof(Hftree)); /*新申請結點node*/
if(!node)return NULL;
node->next=NULL;
node->parent=NULL;
node->lchild=NULL;
node->rchild=NULL; /*置空*/
node->mark=0;
node->ch=character[i];
node->weight=1;

if(tree->next==NULL)
tree->next=node; /*頭結點的下一結點為空,連接node*/

else {
ptr=tree->next;
while(ptr&&ptr->ch!=node->ch) {/*將指針移至鏈表尾*/
ptr=ptr->next;
beforeptr=beforeptr->next; /*後移*/
}
if(ptr&&ptr->ch==node->ch) {/*如果鏈表中某結點的字元與新結點的字元相同*/
/*將該結點的權加一*/
ptr->weight=ptr->weight+1;
free(node); /*釋放node結點的存儲空間*/
}
else {/*新結點與表中結點不相同,將新結點插入鏈表後*/
node->next=beforeptr->next;
beforeptr->next=node; /*node連接在beforeptr之後*/
}
}
}
return tree;
}

/*將整理完的字元串按出現次數從小到大的順序排列 */
linktree taxisnode(linktree tree)
{
linktree head,ph,pt,beforeph; /*head為新鏈表的表頭結點*/

head=(linktree)malloc(sizeof(Hftree));/*創建新鏈表的頭結點*/
if(!head)return NULL;
head->next=NULL; /*新結點的頭結點為空,後續結點也為空*/

ph=head;
beforeph=head;

while(tree->next) {
pt=tree->next;/*取被操作鏈表的首元結點*/
tree->next=pt->next;
pt->next=NULL; /*取出pt所指向的結點*/

ph=head->next;
beforeph=head;

if(head->next==NULL)
head->next=pt;/*創建當前操作鏈表首元結點*/
else {
while(ph&&ph->weight<pt->weight) {/*將被操作結點插入相應位置*/
ph=ph->next;
beforeph=beforeph->next;
}
pt->next=beforeph->next;
beforeph->next=pt;
}
}
free(tree);
return head;
}

/*用排完序的字元串建立霍夫曼樹 */
linktree createHftree(linktree tree)
{
linktree p,q,newnode,beforep;

for(p=tree->next,q=p->next;p!=NULL&&q!=NULL;p=tree->next,q=p->next) {
tree->next=q->next;
q->next=NULL;
p->next=NULL;

newnode=(linktree)malloc(sizeof(Hftree));/*申請新結點作為霍夫曼樹的中間結點*/
if(!newnode)return NULL;
newnode->next=NULL;
newnode->mark=0;

newnode->lchild=p;/*取鏈表頭結點後的兩個結點作為新結點的左、右兒子*/
newnode->rchild=q;
p->parent=newnode;
q->parent=newnode;
newnode->weight=p->weight+q->weight;

p=tree->next;
beforep=tree;

if(p!=NULL&&p->weight>=newnode->weight) {/*將新結點插入原鏈表的相應位置*/
newnode->next=beforep->next;
beforep->next=newnode;
}
else {
while(p!=NULL&&p->weight<newnode->weight) {
p=p->next;
beforep=beforep->next;
}
newnode->next=beforep->next;
beforep->next=newnode;
}
}
return (tree->next);
}

/*對霍夫曼樹進行編碼 */
void Huffmancoding(linktree tree)
{
int index=0;
char *code;
linktree ptr=tree;
code=(char *)malloc(10*sizeof(char));/*此數組用於統計霍夫曼編碼*/

printf("字元以及它的相應權數---------霍夫曼編碼\n\n");
if(ptr==NULL) {
printf("霍夫曼樹是空的!\n");
exit(0);
}
else {
while(ptr->lchild&&ptr->rchild&&ptr->mark==0) {
while(ptr->lchild&&ptr->lchild->mark==0) {
code[index++]='0';
ptr=ptr->lchild;
if(!ptr->lchild&&!ptr->rchild) {
ptr->mark=1;
code[index]='\0';
printf("\tw[%c]=%d\t\t\t",ptr->ch,ptr->weight);
for(index=0;code[index]!='\0';index++)
printf("%c",code[index]);
printf("\n");
ptr=tree;
index=0;
}
}
if(ptr->rchild&&ptr->rchild->mark==0) {
ptr=ptr->rchild;
code[index++]='1';
}
if(!ptr->lchild&&!ptr->rchild) {
ptr->mark=1;
code[index++]='\0';
printf("\tw[%c]=%d\t\t\t",ptr->ch,ptr->weight);
for(index=0;code[index]!='\0';index++)
printf("%c",code[index]);
printf("\n");
ptr=tree;
index=0;
}
if(ptr->lchild->mark==1&&ptr->rchild->mark==1)
{
ptr->mark=1;
ptr=tree;
index=0;
}
}
}
printf("\n");
free(code);
}

/*解碼 */
void decode(linktree tree,char code[])
{
int i=0,j=0;
char *char0_1;
linktree ptr=tree;
char0_1=(char *)malloc(10*sizeof(char));/*此數組用於統計輸入的0、1序列*/

printf("霍夫曼編碼-----相應字元\n\n");
for(j=0,ptr=tree;code[i]!='\0'&&ptr->lchild&&ptr->rchild;j=0,ptr=tree) {
for(j=0;code[i]!='\0'&&ptr->lchild&&ptr->rchild;j++,i++) {
if(code[i]=='0') {
ptr=ptr->lchild;
char0_1[j]='0';
}
if(code[i]=='1') {
ptr=ptr->rchild;
char0_1[j]='1';
}
}
if(!ptr->lchild&&!ptr->rchild) {
char0_1[j]='\0';
for(j=0;char0_1[j]!='\0';j++)
printf("%c",char0_1[j]);
printf("\t\t%c\n",ptr->ch);
}
if(code[i]=='\0'&&ptr->lchild&&ptr->rchild) {
char0_1[j]='\0';
printf("沒有與最後的幾個0、1序列:%s相匹配的字元!\n",char0_1);
return;
}
}
free(char0_1);
}

/*文件*/
inchange()
{
FILE *fp;
char ch;
if((fp=fopen("e10_1.c","rt"))==NULL)
{
printf("Cannot open file strike any key exit!");
getch();
exit(1);
}
ch=fgetc(fp);
while (ch!=EOF)
{
putchar(ch);
ch=fgetc(fp);
}
fclose(fp);

}

/*釋放霍夫曼樹所佔用的空間*/
void deletenode(linktree tree)
{
linktree ptr=tree;
if(ptr) {
deletenode(ptr->lchild);
deletenode(ptr->rchild);
free(ptr);
}
}

void main()
{ int n;
char character[MAXLEN],code[MAXLEN];

FILE *f1;

linktree temp,ht,htree,ptr=NULL;

printf("一、編碼:\n請輸入要測試的字元串:\n\n");
scanf("%s",character);
printf("\n");

temp=tidycharacter(character);

ht=taxisnode(temp);

htree=createHftree(ht);

Huffmancoding(htree);

printf("二、解碼:\n請輸入用於解碼的0、1序列:\n\n");
scanf("%s",code);
printf("\n");

decode(htree,code);

deletenode(htree);
}

希望有用

❾ 哈夫曼編碼的演算法代碼

//本程序根據26個英文字母出現的頻度,得到了它們的一種哈夫曼編碼方案 //by jirgal 2005.4.18 #include<iostream.h> #include<iomanip.h> #define NUM 26 //字母數 #define TNUM 51 // #define LTH 15 //編碼最大長度 class Node { public: char data; int weight; int parent; int lchild; int rchild; }; void main() { char ch[NUM]={'a','b','c','d','e','f','g','h','i','j','k','l', 'm','n','o','p','q','r','s','t','u','v','w','x','y','z'};//26個字母 int weit[NUM]={856,139,279,378,1304,289,199,528,627,13,42, 339,249,707,797,199,12,677,607,1045,249,92,149,17,199,8};//出現頻率 Node nodes[TNUM]; //用對象數組存儲哈夫曼樹 int i,j,one,two,a,b; int hc[NUM][LTH]; //用於存儲編碼 int m,n; //初始化數組 for(i=0;i<NUM;i++) { nodes[i].data=ch[i]; nodes[i].weight=weit[i]; nodes[i].parent=-1; nodes[i].lchild=-1; nodes[i].rchild=-1; } for(i=NUM;i<TNUM;i++) { nodes[i].data='@'; nodes[i].weight=-1; nodes[i].parent=-1; nodes[i].lchild=-1; nodes[i].rchild=-1; } //建立哈夫曼樹 for(i=NUM;i<TNUM;i++) { a=b=-1; one=two=10000; //最大權數 for(j=0;j<i;j++) { if(nodes[j].parent==-1) if(nodes[j].weight<=two) one=two; two=nodes[j].weight; a=b; b=j; } else if(nodes[j].weight>two&&nodes[j].weight<=one) { one=nodes[j].weight; a=j; } } }//for語句得到 parent=-1(即尚沒有父結點)且weight最小的兩個結點 nodes[a].parent=i; nodes[b].parent=i; nodes[i].lchild=a; nodes[i].rchild=b; nodes[i].weight=nodes[a].weight+nodes[b].weight; } //初始化hc for(i=0;i<LTH;i++) { for(j=0;j<NUM;j++) { hc[j][i]=7; } } //編碼 for(i=0;i<NUM;i++) { j=LTH-1; for(m=i,n=nodes[i].parent;m!=-1;m=n,n=nodes[n].parent) { if(nodes[n].lchild==m) { hc[i][j]=0; } else { hc[i][j]=1; } j--; } } //輸出 nodes cout<<"HuffmanTree:"<<endl; cout<<setw(4)<<"NO."<<setw(6)<<"data"<<setw(8)<<"weight"<<setw(6) <<"parnt"<<setw(6)<<"lchd"<<setw(6)<<"rchd"<<endl; for(i=0;i<TNUM;i++) { cout<<setw(4)<<i<<setw(6)<<nodes[i].data<<setw(8)<<nodes[i].weight<<setw(6) <<nodes[i].parent<<setw(6)<<nodes[i].lchild<<setw(6)<<nodes[i].rchild<<endl; } //輸出編碼 cout<<endl<<"Result:"<<endl; cout<<setw(6)<<"char"<<setw(10)<<"frequency"<<setw(16)<<"huffmancode\n"; for(i=0;i<NUM;i++) { cout<<setw(6)<<ch[i]<<setw(8)<<weit[i]; cout<<" "; for(j=0;j<LTH;j++) { if(hc[i][j]!=7) { cout<<hc[i][j]; } } cout<<endl; } cout<<"\nDone.\n"<<endl; }

❿ 哈夫曼編碼/解碼器

生成哈夫曼樹的代碼如下:

#define INT_MAX 10000
#define ENCODING_LENGTH 1000
#include "stdio.h"
#include "string.h"
#include "malloc.h"
typedef enum{none,left_child,right_child} Which;//標記是左孩子還是右孩子
typedef char Elemtype;
typedef struct TNode{
Elemtype letter;
int weight;
int parent;
Which sigh;
char *code;
}HTNode,*HuffmanTree;
int n;
char coding[50];//儲存代碼
char str[ENCODING_LENGTH];//保存要翻譯的句子
void InitTreeNode(HuffmanTree &HT){//初始前N個結點,後M-N個結點置空
int i;int w;char c;
int m=2*n-1;
HuffmanTree p;
HT=(HuffmanTree)malloc((m)*sizeof(HTNode));
printf("input %d database letter and weight",n);
p=HT;
getchar();
for (i=1;i<=n;i++){
scanf("%c%d",&c,&w);
p->code='\0';
p->letter=c;
p->parent=0;
p->sigh=none;
p->weight=w;
p++;
getchar();
}
for (;i<=m;i++,p++){
p->code='\0';
p->letter=' ';
p->parent=0;
p->sigh=none;
p->weight=0;
}
}//INITTREENODE
void Select(HuffmanTree HT,int end,int *s1,int *s2){//在0~END之間,找出最小和次小的兩個結點序號,返回S1,S2
int i;
int min1=INT_MAX;
int min2;
for (i=0;i<=end;i++){//找最小的結點序號
if (HT[i].parent==0&&HT[i].weight<min1){
*s1=i;
min1=HT[i].weight;
}
}
min2=INT_MAX;
for(i=0;i<=end;i++){//找次小結點的序號
if (HT[i].parent==0&&(*s1!=i)&&min2>HT[i].weight){
*s2=i;
min2=HT[i].weight;
}
}
}
void HuffmanTreeCreat(HuffmanTree &HT){//建立HUFFMAN樹
int i;int m=2*n-1;
int s1,s2;
for(i=n;i<m;i++){
Select(HT,i-1,&s1,&s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[s1].sigh=left_child;
HT[s2].sigh=right_child;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}

void HuffmanTreeCode(HuffmanTree HT){//HUFFMAN解碼
int i;
char *temp;
temp=(char *)malloc(n*sizeof(char));
temp[n-1]='\0';
int p;int s;
for (i=0;i<n;i++){
p=i;
s=n-1;
while (HT[p].parent!=0){//從結點回溯,左孩子為0,右孩子為1
if (HT[p].sigh==left_child)
temp[--s]='0';
else if (HT[p].sigh==right_child)
temp[--s]='1';
p=HT[p].parent;
}
HT[i].code=(char *)malloc((n-s)*sizeof(char));//分配結點碼長度的內存空間
strcpy(HT[i].code,temp+s);
printf("%s\n",HT[i].code);
}
}
void GetCodingSen(char *sencence){//輸入要編碼的句子
int l;
gets(sencence);
l=strlen(sencence);
sencence[l]='\0';
}
void HuffmanTreeEncoding(char sen[],HuffmanTree HT){//將句子進行編碼
int i=0;int j;
while(sen[i]!='\0'){
for(j=0;j<n;j++){
if (HT[j].letter==sen[i]) //字母吻合則用代碼取代
{strcat(coding,HT[j].code);
break;
}
}
i++;
if (sen[i]==32) i++;
}
printf("\n%s",coding);
}
void HuffmanTreeDecoding(HuffmanTree HT,char code[]){//HUFFMAN解碼過程,將代碼翻譯為句子
char sen[100];
char temp[50];
char voidstr[]=" ";
int i;int j;
int t=0;int s=0;
for(i=0;i<strlen(code);i++){
temp[t++]=code[i];
for(j=0;j<n;j++){
if (strcmp(HT[j].code,temp)==0){//代碼段吻合
sen[s]=HT[j].letter;s++;
strcpy(temp,voidstr);//將TEMP置空
t=0;
break;
}
}
}
printf("\n%s",sen);
}

void main(){
HTNode hnode;
HuffmanTree huff;
huff=&hnode;
printf("input the letter for coding number\n");
scanf("%d",&n);
InitTreeNode(huff);
HuffmanTreeCreat(huff);
HuffmanTreeCode(huff);
GetCodingSen(str);
HuffmanTreeEncoding(str,huff);
HuffmanTreeDecoding(huff,coding);
}

閱讀全文

與哈夫曼樹編譯器程序代碼相關的資料

熱點內容
仿微信聊天系統源碼廣州公司 瀏覽:104
怎麼查看我的世界伺服器日誌 瀏覽:428
怎麼從程序員走到成功 瀏覽:820
把軟體放入文件夾中如何移出 瀏覽:205
紅包源碼企業即時聊天軟體 瀏覽:576
xp安裝python 瀏覽:8
西門子參數編程讀取半徑值 瀏覽:399
洗首飾解壓小視頻 瀏覽:964
01背包問題的演算法解決 瀏覽:373
sd卡放哪個文件夾 瀏覽:301
解釋器模式java 瀏覽:104
android垂直自動滾動條 瀏覽:153
計算器java小程序 瀏覽:27
java的簡稱 瀏覽:68
雲伺服器公網ip地址 瀏覽:580
php對資料庫操作 瀏覽:237
java爬圖片 瀏覽:866
汽車小壓縮機拆解 瀏覽:830
雲桌面卡是因為伺服器的原因嗎 瀏覽:381
qd123壓縮機 瀏覽:974