1. 程式人生 > >霍夫曼樹和霍夫曼編碼

霍夫曼樹和霍夫曼編碼

#include <stdio.h>
#include <stdlib.h>
#include <cstring>
using namespace std;

typedef struct HuffNode
{
	int weight;
	int parent, lchild, rchild;
}HuffNode, HuffTree;

void select(HuffTree* H, int m, int* s1, int* s2)
//在索引為0~m的元素中找到**parent為0**且權重最小的兩個元素的索引s1,s2
{
	//初始化兩個最小的元素min1,與min2, 且min1<min2
	int min1 = 500;
	int min2 = 1000;
	int min1_index, min2_index = 1000;
	for(int i = 0; i<=m; i++)
	{
		if(H[i].parent==0)    //這個條件很重要!!它使得前一次被選中的根節點在這次選擇中不會被選中
		{
			if(H[i].weight < min1)  //則當前元素<min1<min2, 應將min2用min1賦值, 再將當前元素賦給min1
			{
			min2 = min1;
			min2_index = min1_index;
			min1 = H[i].weight;
			min1_index = i;
			continue;
			}
			if(H[i].weight < min2)   //則min1<當前元素<min2, 應將當前元素賦給min2
			{
			min2 = H[i].weight;
			min2_index = i;
			}
		}

	}
	*s1 = min1_index;
	*s2 = min2_index;

}

void display(HuffTree* H, int n)
{
	for(int i = 0; i<=n-1; i++)
	{
		printf("%d, weight:%d, parent:%d, lchild:%d, rchild:%d\n", i, H[i].weight, H[i].parent, H[i].lchild, H[i].rchild);
	}
}


void HuffmanCoding(int n, HuffTree* H, char** HuffCode, int w[])
{
	//n個葉子結點, n-1個非葉子結點.共2n-1個結點
	int m = 2*n-1;
	//為線性儲存結構分配空間
	H = (HuffNode *)malloc(sizeof(HuffNode)*m);  
	HuffNode* p = H;
	int * p_w = w;
	//對前n個葉子結點,其權重等於w[]中的元素值
	for(int i = 0; i<=n-1; i++)
	{
		//*p = {*p_w, 0,0,0};//這句話的作用等價於下面四句:
		H[i].weight = *p_w;
		H[i].parent = 0;
		H[i].lchild = 0;
		H[i].rchild = 0;

		p++;
		p_w++;
	}

	//對後n-1個非葉子結點,其權重0
	for(int i = n; i<=m-1; i++)
	{
		//*p = {0,0,0,0};

		H[i].weight = 0;
		H[i].parent = 0;
		H[i].lchild = 0;
		H[i].rchild = 0;
		p++;
	}
	//對n-1個非葉子結點
	for(int i = n; i<=m-1; i++)
	{
		int s1, s2 = 0;
		select(H, i-1, &s1, &s2);//在前i-1個元素中找到parent為0且權重最小的兩個元素的索引s1,s2
		H[i].lchild = s1;
		H[i].rchild = s2;
		H[i].weight = H[s1].weight + H[s2].weight;
		H[s1].parent = i;
		H[s2].parent = i;
		display(H, m);
	}

	display(H, m);

	//為二維霍夫曼編碼結構分配空間, 共n個元素, 每個元素是一個char*型別的指標
	HuffCode = (char**)malloc(sizeof(char*)*(n));
    	if(!HuffCode)
		printf("error to malloc for HUffCode.");

	//為每一個字元編碼首先預分配長度為n的空間,	
	char * codestring = (char*)malloc(sizeof(char)*n);
	codestring[n-1] = '\0';
	//從葉子結點到根逆向求每個字元的Huffmancode
	for(int i = 0; i<=n-1; i++)
	{
		int start_index = n-2;

		int c = i;   //initialize index of current node to index of the first leaf node
		int f = H[c].parent;  //initialize the inde of current parent
		while(f!=0)
		{
			if(H[f].lchild == c)
				codestring[start_index--] = '0';
			if(H[f].rchild == c)
				codestring[start_index--] = '1';
			c = f;
			f = H[c].parent;
		}

		//由於HuffCode的每一維都是一個指標, 因此, 這裡對每個指標分配長度為n-1-start_index的空間
		HuffCode[i]=(char *)malloc((n-1-start_index)*sizeof(char));
		strcpy(HuffCode[i], &(codestring[start_index+1]));

		printf("code string[%d] is:%s\n",i, &(codestring[start_index+1]));
	}
	free(codestring);
	codestring=NULL;

}




int main()

{
	int w[] = {5,29,7,8,14,23,3,11};
	HuffTree H;
	char **HuffCode;
	HuffmanCoding(8, &H, HuffCode, w);
}

執行結果:


注意:

霍夫曼編碼並不是唯一的,只要平均帶權路徑長度最小就OK.

相關推薦

編碼

#include <stdio.h> #include <stdlib.h> #include <cstring> using namespace std; typedef struct HuffNode { int weight;

編碼

赫夫曼樹,又稱最優樹,是一類帶權路徑長度最短樹。 從樹中一個節點到另一個節點之間的分支構成這兩個節點之間的路徑,路徑上的分支數目稱為路徑長度。樹的路徑長度指的是從樹根到樹中其他每個節點的路徑長度之和。節點的帶權路徑長度是指從樹的根節點到該節點之間的路徑長度與該節點上所帶權值

資料結構:赫編碼的儲存表示

#include <stdio.h> #include <stdlib.h> #include <string.h> #define UINT_MAX 100 //假設各結點的權值不會超過100 typedef struct { unsigned int weigh

編碼

image bsp alt ima 技術分享 img http 哈夫曼 info 哈夫曼樹和哈夫曼編碼

java 二叉(十三) 哈編碼

一般可以按下面步驟構建: 1,將所有左,右子樹都為空的作為根節點。 2,在森林中選出兩棵根節點的權值最小的樹作為一棵新樹的左,右子樹,且置新樹的附加根節點的權值為其左,右子樹上根節點的權值之和。注意,左子樹的權值應小於右子樹的權值。 3,從森林中刪除這兩棵樹,同時把新樹加入

C語言資料結構——赫編碼

1、赫夫曼樹又稱最優樹,是一類帶權路徑長度最短的樹。 2、從樹的一個結點到另一個結點之間的分支構成這兩個結點之間的路徑,路徑上的分支數目稱為路徑長度。樹的路徑長度是從樹根到每個結點的路徑長度之和。

編碼

問題:根據學生的百分制成績計算5級分製成績,成績在5個等級上的分佈規律: 分數 0-59 60-69 70-79 80-89 90-100 所佔比例 5% 15% 40% 30% 10% 圖二叉樹a中可以看出70分以上大約佔總數80%的成績都要經過3次以上的判斷才能得到結果

Java 結構實際應用 二(哈編碼

 赫夫曼樹 1 基本介紹 1) 給定 n 個權值作為 n 個葉子結點,構造一棵二叉樹,若該樹的帶權路徑長度(wpl)達到最小,稱這樣的二叉樹為 最優二叉樹,也稱為哈夫曼樹(Huffman Tree), 還有的書翻譯為霍夫曼樹。 2) 赫夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近  

(Huffman)編碼

選擇 其中 有一個 只有一個 bsp nbsp 例子 left style 一、哈夫曼(Huffman)樹和哈夫曼編碼 1.哈夫曼樹(Huffman)又稱最優二叉樹,是一類帶權路徑長度最短的樹, 常用於信息檢測。 定義: 結點間的路徑長度:樹中一個結點到另一個結點之間分

資料結構——第二章森林:04哈與哈編碼

1.結點的路徑長度:從根結點到該結點的路徑上分支的數目。 2.樹的路徑長度:樹中每個結點的路徑長度之和。 3.樹的帶權路徑長度:樹中所有葉子結點的帶權路徑長度之和WPL(T) = ∑wklk(對所有葉子結點) 4.最優樹:在所有含n個結點,並帶相同權值的m叉樹中,必存在一棵其帶權路徑長度取最小值的樹,稱

數據結構——第二章森林:04哈與哈編碼

一個 例如 stat state 森林 ont 技術 圖片 http 1.結點的路徑長度:從根結點到該結點的路徑上分支的數目。 2.樹的路徑長度:樹中每個結點的路徑長度之和。 3.樹的帶權路徑長度:樹中所有葉子結點的帶權路徑長度之和WPL(T) = ∑wklk(對所有葉子結

及哈編碼解碼

哈夫曼樹,又稱最優樹,是帶權路徑最小的樹。 基本概念: 節點間的路徑長度:兩個節點間所包含的邊的數目。 樹的路徑長度:從根到樹中任意節點的路徑長度之和。 權:將節點賦予一定的量值,該量值成為權。 樹的帶權路徑長度:樹中所有葉子結點的帶權路徑長度。 哈夫曼演算法:給定一個儲存權值的陣列,求

資料結構之---C語言實現哈編碼

//哈夫曼樹 //楊鑫 #include <stdio.h> #include <stdlib.h> typedef int ElemType; struct BTreeNode { ElemType data; struct BTr

利用優先佇列編寫哈編碼

利用“有序連結串列”來實現優先佇列,連結串列元素按優先順序遞減。元素出列即出首元素,元素入列即將元素插入有序連結串列使其依然有序。本程式中,字元頻率小則優先順序高。 typedef int PQEl

的帶權路徑長度

樹的帶權路徑長度(Weighted Path Length of Tree):定義為樹中所有葉結點的帶權路徑長度之和。 結點的帶權路徑長度:結點到樹根之間的路徑長度與該結點上權的乘積。 哈夫曼樹是一種帶權路徑長度最短的二叉樹,也稱為最優二叉樹。 例:對於給定的一組

OpenCV中的線變換圓變換

word 得到 統計 不同 效率 兩種 做的 ndis pan 一、霍夫線變換 霍夫線變換是OpenCv中一種尋找直線的方法,輸入圖像為邊緣二值圖。 原理: 一條直線在圖像二維空間可由兩個變量表示, 例如: 1、在 笛卡爾坐標系: 可由參數: (m,b) 斜率和截距表示。

5.2哈——哈與哈編碼

node i++ insert 編碼 urn all IV right style #include <stdio.h> #include <stdlib.h> struct TreeNode{ int Weight; Huffm

直線變換圓變換的原理實現

一、霍夫直線的原理 (1)本部分大部分學習來自《OpenCV3程式設計入門》,另外有一些自己的理解 如上圖所以,將一條直線由截距是表示為在極座標系下 化簡為 (2)對於一個點(x0,y0)來說,可以通過這個點的一族直線統一定義為 每一對  代表一條通

及哈編碼

哈夫曼樹 哈夫曼樹,最優二叉樹,帶權路徑長度(WPL)最短的樹。它沒有度為1的點,是一棵嚴格的二叉樹(滿二叉樹)。 何謂‘帶權路徑長度’ 瞭解哈夫曼樹,我們首先要知道樹的幾個相關術語,並瞭解什麼是WPL。 路徑:從樹中一個結點到另一個結點之間的分支構成兩個結點

【資料結構】哈及哈編碼

哈夫曼樹 給定n個權值作為n個葉子結點,構造一棵二叉樹,若帶權路徑長度達到最小,稱這樣的二叉樹為最優二叉樹,也稱為哈夫曼樹(Huffman Tree)。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。 樹節點間的邊相關的數叫做權。 從樹