哈夫曼树(最优二叉树)的构造【二叉树的应用】

        对于给定一个长度为m序列,构造一颗以序列值为权的m个外部结点的扩充二叉树,使得带权的外部路径长度WPL最小,就称这颗扩充二叉树为 哈夫曼(Huffman)树(最优二叉树)。构造Huffman Tree 的算法也就是哈夫曼算法。

算法基本思想:

1)给定m个权值,首先构造m课扩充二叉树,每颗只有一个外部结点(根结点)。

2)在已经构造的所有扩充二叉树中,选择根结点权值最小的和次小的两颗,将它们作为左、右子树,构造一颗新的扩充二叉树,它的根结点的权值为其左右子树根结点的权值之和。

3)重复2),每次使得扩充二叉树的数目减一,当只剩下最后一颗扩充二叉树时,其便是所求的哈夫曼树。


代码实现:

#include 
#define MAXINT 10000
#define N 13                        //构建13个结点
using namespace std;

struct HtNode{
    int var,parent,llink,rlink;
};
struct HtTree{
    int m,root;                     //外部结点个数、根结点在ht数组中的下标
    struct  HtNode *ht;
};
typedef struct HtTree * PHtTree;

void print(PHtTree p)
{
    cout<<"index var parent lchild rchild\n";
    for(int i=0;i<2*N-1;i++)
        cout<ht[i].var<<"   "<ht[i].parent<<"     "
            <ht[i].llink<<"     "<ht[i].rlink<ht=new HtNode[2*m-1];      //外部结点为m,则内部结点为m-1,则总共点数为2m-1
    for(int i=0;i<2*m-1;i++){       //置ht数组初态
        pht->ht[i].llink=pht->ht[i].rlink=pht->ht[i].parent=-1;
        pht->ht[i].var= iht[j].varht[j].parent==-1){
                m2=m1;x2=x1;
                m1=pht->ht[j].var; x1=j;
            }                       //找次最小权的无父节点的结点
            else if(pht->ht[j].varht[j].parent==-1){
                m2=pht->ht[j].var;x2=j;
            }
        }
                                    //构造内部结点
        pht->ht[x1].parent=pht->ht[x2].parent=m+i;
        pht->ht[m+i].var=m1+m2;
        pht->ht[m+i].llink=x1;
        pht->ht[m+i].rlink=x2;
    }
    pht->root=2*m-2;
    return pht;
}
int main()
{
    int sequence[N];
    for(int i=0;i>sequence[i];
    PHtTree p=huffman(N,sequence);
    cout<<"数组ht的终态:\n";
    print(p);
    return 0;
}

时间复杂度为O(n^2)。


Input

2 3 5 7 11 13 17 19 23 29 31 37 41

Output

数组ht的初态:
index var parent lchild rchild
0       2   -1     -1     -1
1       3   -1     -1     -1
2       5   -1     -1     -1
3       7   -1     -1     -1
4       11   -1     -1     -1
5       13   -1     -1     -1
6       17   -1     -1     -1
7       19   -1     -1     -1
8       23   -1     -1     -1
9       29   -1     -1     -1
10      31   -1     -1     -1
11      37   -1     -1     -1
12      41   -1     -1     -1
13      -1   -1     -1     -1
14      -1   -1     -1     -1
15      -1   -1     -1     -1
16      -1   -1     -1     -1
17      -1   -1     -1     -1
18      -1   -1     -1     -1
19      -1   -1     -1     -1
20      -1   -1     -1     -1
21      -1   -1     -1     -1
22      -1   -1     -1     -1
23      -1   -1     -1     -1
24      -1   -1     -1     -1
数组ht的终态:
index var parent lchild rchild
0       2   13     -1     -1
1       3   13     -1     -1
2       5   14     -1     -1
3       7   15     -1     -1
4       11   16     -1     -1
5       13   16     -1     -1
6       17   17     -1     -1
7       19   18     -1     -1
8       23   18     -1     -1
9       29   19     -1     -1
10      31   20     -1     -1
11      37   21     -1     -1
12      41   21     -1     -1
13      5   14     0     1
14      10   15     2     13
15      17   17     3     14
16      24   19     4     5
17      34   20     6     15
18      42   22     7     8
19      53   22     16     9
20      65   23     10     17
21      78   23     11     12
22      95   24     18     19
23      143   24     20     21
24      238   -1     22     23
        注意,结果中index表示数组ht的下标,意味着各节点之间的关系,例如(下标为0的)结点2和(下标为1的)结点3的父节点(下标为13)为5,再看下标的13的结点5,它的左孩子是(下标为0的)结点2,右孩子为(下标为1的)结点3。

构造的哈夫曼树如下,

哈夫曼树(最优二叉树)的构造【二叉树的应用】_第1张图片

你可能感兴趣的:(算法与数据结构,哈夫曼算法,Huffman,哈夫曼树,最优二叉树)