最优二叉树

最优二叉树(哈夫曼树)

	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;
		}
		
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值