構造哈夫曼樹並求帶權路徑長度(c語言/CodeBlocks實現)
阿新 • • 發佈:2019-02-09
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
using namespace std;
int w[100], n, wpl = 0;
typedef struct node{
int data;
struct node *l, *r;
}HfmNode;
void CreateHfmTree(int *w, int n)
{
int i, j;
HfmNode *b[100 ], *p;
for(i = 0; i < n; i++){ //構造n棵僅有一個根節點的樹b[i]
b[i] = (HfmNode *)malloc(sizeof(HfmNode*));
b[i]->data = w[i];
b[i]->l = NULL;
b[i]->r = NULL;
}
for(i = 0; i < n - 1; i++){ //注意這裡是n-1次迴圈,即最後得到的根節點不用再迴圈一次了
int k1 = -1, k2; //k1表示森林中具有最小權值的樹根結點的下標,k2為次最小的下標
for(j = 0; j < n; j++){ //讓k1初始指向森林中第一棵樹,k2指向第二棵;b[j]=NULL表示刪除另外這棵樹
if(b[j] != NULL && k1 == -1){//至於為什麼要讓k1=-1,只是個標誌而已,為了讓k1指向第一個非空結點
k1 = j;
continue;
}
if(b[j] != NULL){
k2 = j;
break ;
}
}
for(j = k2; j < n; j++){ //從當前森林中求出最小權值樹和次最小
if(b[j] != NULL){
if(b[j]->data < b[k1]->data){
k2 = k1;
k1 = j;
}
else if(b[j]->data < b[k2]->data)
k2 = j;
}
}
p = (HfmNode *)malloc(sizeof(HfmNode*));
p->data = b[k1]->data + b[k2]->data;
wpl += p->data; //求帶權路徑長
p->l = b[k1];
p->r = b[k2];
b[k1] = p; //新增p這棵樹到b[k1]
b[k2] = NULL; //刪除b[k2]這棵樹
}
free(b);
return;
//return p; 可返回整棵樹的根指標
};
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &w[i]);
CreateHfmTree(w, n);
printf("%d\n", wpl);
return 0;
}
(程式碼有參考,忘記參考哪篇了…請見諒。略有改動)