1. 程式人生 > >哈夫曼樹建立演算法

哈夫曼樹建立演算法

哈夫曼樹的建立

 Problem Description

由若干個值無重複的結點及其權值,建立相應的哈夫曼樹。在合併過程中,若出現權值相同的情況,則優先選取編號小的進行合併;要求哈夫曼樹中所有左孩子編號小於右孩子編號(以結點的輸入順序做為其編號)。

 Input

有多組測試資料,每組資料由結點資訊組成。結點資訊部分的第一行為一個整數n(n<=20),表示以下有n個結點資訊,每個結點資訊包括一個字元和一個整數,表示結點值和權值。

 Output

輸出儲存哈夫曼樹的陣列,每個結點資訊佔一行,每組輸出結果後均有一空行。

 Sample Input

4
A7
G5
O2
D4
 

 Sample Output

7,6,-1,-1
5,5,-1,-1
2,4,-1,-1
4,4,-1,-1
6,5,2,3
11,6,1,4
18,-1,0,5

 

#include <iostream>
#include<stdio.h>
using namespace std;

struct node {
    int parent;
    int lchild,rchild;
    int weight;
};

node* array;
int select_min(int n) {

    int minIndex;
    for(int i=0;i<2*n-1;i++){
        if(array[i].parent==-1&&array[i].weight!=0) {
            minIndex=i;break;
        }
    }
    for(int i=0; i<2*n-1; i++) {
        if(array[i].parent==-1&&array[i].weight!=0) {
            if(array[i].weight<array[minIndex].weight)
                minIndex=i;
        }
    }
    array[minIndex].parent=1;
    return minIndex;
}

void CreatHuffman(int *w,int n) {
    for(int i=0; i<2*n-1; i++) {
        array[i].parent=-1;
        array[i].lchild=-1;
        array[i].rchild=-1;
        array[i].weight=w[i];
    }
    for(int j=n; j<2*n-1; j++) {
        int min_lchild=select_min(n);
        int min_rchild=select_min(n);
        array[j].lchild=min_lchild;
        array[j].rchild=min_rchild;
        array[j].weight=array[min_lchild].weight+array[min_rchild].weight;
        array[min_lchild].parent=j;
        array[min_rchild].parent=j;
    }

}

void showData(int n) {
    for(int i=0; i<2*n-1; i++) {
        cout<<array[i].weight<<","<<array[i].parent<<","<<array[i].lchild<<","<<array[i].rchild<<endl;
    }

}

int main() {
 
    int n;
    while(cin>>n) {
        array=new node[2*n-1];
        int *w=new int[2*n-1];
        for(int i=0; i<n; i++) {
            char ch;
            cin>>ch>>w[i];
        }
        for(int i=n; i<2*n-1; i++)
            w[i]=0;


        CreatHuffman(w,n);
        showData(n);
        cout<<endl;
    }
    return 0;
}