哈夫曼樹的建立(輸入權值)與遍歷

2021-09-29 20:25:02 字數 3840 閱讀 1602

我是乙個大二的學渣,第一次寫的部落格,有什麼不對的地方還請各位大佬,朋友們不吝賜教。謝謝大家

首先定義哈夫曼樹節點的結構體

其中weight儲存輸入的權重(預設輸入的都是int型別)。因為我們後面是要用陣列儲存所有樹節點,所以用int型別定義父節點和左右孩子節點的下標。

struct htnode

;

建立哈夫曼樹

1.動態分配記憶體,給節點初始化

輸入n個權重,申請2n大小的記憶體。因為有n個權重就會產生n-1個新節點,所以總節點數為2n-1,但是為了方便,第一號(即下標為0)的空間空出,不做操作。

把每個父節點和左右孩子全都初始化為0。

htnode *arr =

(htnode *

)malloc

(sizeof

(htnode)*2

* n)

;for

(int i =

1; i <= n; i++

)for

(int i =

0; i < n *

2; i++

)

找出兩個最小的權值在陣列的下標

每次找下標都是先找出最大權值,然後通過最大權值,找到最小權值所在的下標。

//引數分別是儲存節點的下標、最小的位置、第二小的位置、鍵盤輸入節點個數、新生成節點個數

void

mintow

(htnode *

&arr,

int&pos_1,

int&pos_2,

int n,

int number_new_node)

}//pos_1

for(

int i =

1; i <= n + number_new_node; i++)}

//找pos_2

min = arr[1]

.weight;

//找最大權值

for(

int i =

1; i <= n + number_new_node; i++)}

//pos_2

for(

int i =

1; i <= number_new_node + n; i++)}

}

生成新節點

這裡的number_new_node代表新生成的節點數(會在前面**定義)。

修改新節點的左右孩子、權值,和左右孩子的父節點。

//產生新的節點

number_new_node++;

arr[n + number_new_node]

.weight = arr[pos_1]

.weight + arr[pos_2]

.weight;

arr[n + number_new_node]

.left = pos_1;

arr[n + number_new_node]

.right = pos_2;

//修改權值最小節點的父節點

arr[pos_1]

.parent = n + number_new_node;

arr[pos_2]

.parent = n + number_new_node;

所以建立樹的完整的**:

htnode*

createhuffmantree

(int n)

for(

int i =

0; i < n *

2; i++

)int number_new_node =0;

//新生成節點的值

//建立哈夫曼樹

for(

int k =

1; k < n; k++

)return arr;

}

遍歷哈夫曼樹

跟遍歷二叉樹的過程是一樣的

我這裡用的是前序遍歷。

void

orderhaffmantree

(int num, htnode*

&arr)

cout << arr[num]

.weight <<

" ";

orderhaffmantree

(arr[num]

.left, arr)

;orderhaffmantree

(arr[num]

.right, arr)

;}

以下就是完成的**

#include

#include

using

namespace std;

//哈夫曼樹結點結構體

struct htnode

;void

mintow

(htnode *

&arr,

int&pos_1,

int&pos_2,

int n,

int number_new_node)

}for

(int i =

1; i <= n + number_new_node; i++)}

//找pos_2

min = arr[1]

.weight;

for(

int i =

1; i <= n + number_new_node; i++)}

for(

int i =

1; i <= number_new_node + n; i++)}

}//建立haffman樹

htnode*

createhuffmantree

(int n)

for(

int i =

0; i < n *

2; i++

)int number_new_node =0;

//新生成節點的值

//建立哈夫曼樹

for(

int k =

1; k < n; k++

)return arr;

}//哈夫曼樹的遍歷(前序遍歷)

void

orderhaffmantree

(int num, htnode*

&arr)

cout << arr[num]

.weight <<

" ";

orderhaffmantree

(arr[num]

.left, arr)

;orderhaffmantree

(arr[num]

.right, arr);}

intmain()

要說一下為什麼一開始在主函式遍歷操作輸入的引數是2*n-1。

因為當哈夫曼樹建立完了之後,根節點就是parent值為0的節點,而且只有在最後乙個生成的節點的parent的值為0,所以就取了最後一位節點的下標。

例項如下:

這裡輸入了六個節點的權值,建立的樹如下:

紅色為新生成的節點,因為每一輪迴圈總有pos_1因為本人能力有限,如果有什麼錯誤或者可以改進的地方,還請各位大佬不吝賜教。謝謝。

求哈夫曼樹的權值

哈夫曼樹,第一行輸入乙個數n,表示葉結點的個數。需要用這些葉結點生成哈夫曼樹,根據哈夫曼樹的概念,這些結點有權值,即weight,題目需要輸出所有結點的值與權值的乘積之和。輸入有多組資料。每組第一行輸入乙個數n,接著輸入n個葉節點 葉節點權值不超過100,2 n 1000 輸出權值。5 1 2 2 ...

哈夫曼樹 哈夫曼樹求帶權路徑和

首先要了解哈夫曼樹的一些概念 帶權路徑 每個葉子結點都有權值,對於某葉子結點來說,它的帶權路徑就是 結點權值 從根節點到該結點的路徑長度 哈夫曼樹的構造方法 兩個權值最小的葉子結點作為兄弟去構成乙個非葉節點。該父親非葉節點的權值 二者之和 之前我只知道這些基本概念,求帶權路徑和的時候也只是 數數 數...

哈夫曼樹與哈夫曼編碼

在一般的資料結構的書中,樹的那章後面,著者一般都會介紹一下哈夫曼 huffman 樹和哈夫曼編碼。哈夫曼編碼是哈夫曼樹的乙個應用。哈夫曼編碼應用廣泛,如 jpeg中就應用了哈夫曼編碼。首先介紹什麼是哈夫曼樹。哈夫曼樹又稱最優二叉樹,是一種帶權路徑長度最短的二叉樹。所謂樹的帶權路徑長度,就是樹中所有的...