最优二叉树(哈夫曼树)
1.权值:每一个叶子结点所对应的一个有实际意义的数据。
2.带权路径长度:路径长度所指的是由根节点到所有叶子节点的路径长度之和。而带权路径长度则是各个叶子结点的路径长度与相应的结点权值的乘积之和。
3.最优二叉树:由相同权值的一组叶子结点所构成的二叉树可能有不同的形态和不同的带权路径长度,具有最小带全路径长度的二叉树成为最优二叉树。
算法实现:类的定义:
class Tree{
int value;
int leftChild;//左孩子的下标
int rightChild;//右孩子的下标
int parent;//父节点的下标
}
构建最优二叉树的思想是先寻找最小权值结点和次小权值结点组成一个二叉树,根节点的权值是两个结点之和,然后再找最小权值节点和次小权值结点组成一个二叉树,最后直到所有的节点都在一颗二叉树里。
其中,value保存节点的权值,left.right和parent分别保存该结点左右孩子和父节点的指针(下标),通过parent来确定某结点是不是一个二叉树的根节点,因为每次都选择根节点的权值为最小和次小的两个树,当某节点的parent等于-1的时候,证明其没有父节点,可以作为根节点。
代码实现:用数组来对最优二叉树进行储存
void CreatTree(Tree HFMTree[],int n){
int maxValue=100;
Scanner scanner=new Scanner(System.in);
int m1 = 0,x1,m2 = 0,x2;//x1,x2储存最小和次小权值,m1,m2储存其位置
int i;
for (i = 0; i < n; i++) {
HFMTree[i].value=scanner.nextInt();
}
for (i = 0; i < n-1; i++) {
x1=x2=maxValue;
m1=m2=0;
for (int j = 0; j < n+i; j++) {
if(HFMTree[j].parent==-1&&HFMTree[i].value<x1){
//如果任一结点的权值小于x1,x1进行替换
x2=x1;
m2=m1;
x1=HFMTree[i].value;
m1=j;
}
else if (HFMTree[j].parent==-1&&HFMTree[j].value<x2) {
//如果任一结点的权值大于x1但是小于x2,对x2进行替换
x2=HFMTree[j].value;
m2=j;
}
}
//将找出的最小和次小权值的两个结点合并成一棵树
HFMTree[m1].parent=n+i;//设置两个结点的父节点
HFMTree[m2].parent=n+i;
HFMTree[n+i].value=HFMTree[m1].value+HFMTree[m2].value;//设置父节点的权值
HFMTree[n+i].left=m1;//给父节点的左右孩子指针设置指向
HFMTree[n+i].right=m2;
}
}