我是乙個大二的學渣,第一次寫的部落格,有什麼不對的地方還請各位大佬,朋友們不吝賜教。謝謝大家
首先定義哈夫曼樹節點的結構體
其中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中就應用了哈夫曼編碼。首先介紹什麼是哈夫曼樹。哈夫曼樹又稱最優二叉樹,是一種帶權路徑長度最短的二叉樹。所謂樹的帶權路徑長度,就是樹中所有的...