算法连载(3)--生成最优归并树

1.问题描述:把N个已分类的文件通过成对地重复归并已分类的文件归并在一个文件中。例如,假定X1,X2,X3,X4是要归并的文件,则可以首先把X1,X2归并成Y1,然后Y1和X3归并成Y2,最后Y2和X4归并,从而得到要的分类文件。运用最优二路归并方法,归并出来的结果都有想对应的最小权带外部路径的二元树,所以把问题转换为由N棵根结点带权值的树组成的森林,归并成为一棵二元树。

2.设计思想与分析:
    基本思路:(1)假设给定的一组权值{W1,W2,……,Wn},由此可以产生出由N棵二元树组成的森林F={T1,T2,……,Tn},其中每棵树都有一个权值为Wi的根结点;(2)在森林F中选出两棵树根结点的权值最小的树,作为一棵新树的左右子树且置新树的根结点的权值为其左右子树的根结点的权值之和;(3)从森林F中删去分别做为左右子树的这两棵树,同时将新树加入到集合F中;(4)对新的森林重复2,3步骤,直到F中只剩一棵二元树时为止,这就是所要的树了。

#include "iostream.h"
struct HuffmanNode 
{
 int weight;
 int parent;
 int lchild,rchild;
};structure of node
///

class HuffmanTree 
{
public:
 HuffmanNode *Node;
public:
Tree(int weightnum);
};huaffmantree class
HuffmanTree::Tree(int weightnum)
{
 
  int i , j, pos1,pos2;
  int min1,min2;
 
 Node=new struct HuffmanNode [2*weightnum-1];
 for (i=0;i<weightnum;i++)
 { 
  cout<<"请输入第"<<i+1<<"个字符的权值:";
  cin>>Node[i].weight;
  Node[i].parent=-1;  
  Node[i].lchild=-1; 
  Node[i].rchild=-1; 
 }
/*join and creat tree*///
 for (i=weightnum; i<2*weightnum-1; i++) {
  pos1=-1;  pos2=-1;
  min1=min2=32762;
  j=0;
  while(j<=i-1)
  {
   if (Node[j].parent==-1)
   {
    if(Node[j].weight<=min1)
    {  min2=min1; min1=Node[j].weight;
              pos2=pos1; pos1=j; }
    else
     if(Node[j].weight<min2)
     { min2=Node[j].weight; pos2=j; }
   }
   j++;
   
  }//while
   Node[pos1].parent=i;
   Node[pos2].parent=i;
   Node[i].lchild=pos1;
   Node[i].rchild=pos2;
   Node[i].parent=-1;  
   Node[i].weight=Node[pos1].weight+Node[pos2].weight;
 }//for
 j=2*weightnum-2;
 int l,r;
while(Node[j].lchild!=-1||Node[j].rchild!=-1)
{
 cout<<"root is:"<<Node[j].weight<<" ";
 l=Node[j].lchild;
 r=Node[j].rchild;
 cout<<"lchild is:"<<Node[l].weight<<" ";
 cout<<"rchild is:"<<Node[r].weight<<" ";
 cout<<endl;
 j--;
}
} //creat a Btree
///
void  main()
{ cout<<"|--------生成最优的二元归并树---------|"<<endl;
 cout<<"|---power by zhanjiantao(028054115)---|"<<endl;
 cout<<"|-------------------------------------|"<<endl;
 int i;
 while(i)
 {
 int weightnum;
 cout<<"请输入权值的个数: ";
 cin>>weightnum;
 HuffmanTree t;
 t.Tree(weightnum);
 cout<<"Press<1> to run again"<<endl;
 cout<<"Press<0> to exit"<<endl;
 cin>>i;
 }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最小生成最优二叉是两个不同的算法,分别用于解决不同的问题。 最小生成算法用于在一个连通无向图中找到一棵包含所有顶点的,并且使得的边的权值之和最小。其中,常用的最小生成算法有Prim算法和Kruskal算法。 Prim算法的步骤如下: 1. 选择一个起始顶点作为的根节点。 2. 从与相邻的顶点中选择一个权值最小的边,并将该边和相邻的顶点加入到中。 3. 重复步骤2,直到包含了所有的顶点。 Kruskal算法的步骤如下: 1. 将图中的所有边按照权值从小到大进行排序。 2. 依次选择权值最小的边,如果该边的两个顶点不在同一个连通分量中,则将该边加入到最小生成中。 3. 重复步骤2,直到最小生成包含了所有的顶点。 最优二叉,也称为哈夫曼,是一种特殊的二叉,用于编码和解码数据。哈夫曼的构造过程如下: 1. 将给定的n个权值构成n棵只有一个节点的,并根据权值由小到大进行排序。 2. 取权值最小的两棵作为左右子构成一颗新二叉,新二叉的权值为两棵的权值之和。 3. 将构造的新放入序列的最左边。 4. 重复步骤2和3,直到所有合并为一棵为止。 最终得到的就是哈夫曼,也就是最优二叉。 以下是哈夫曼生成代码的示例: ```python # 定义节点类 class Node: def __init__(self, value, weight): self.value = value self.weight = weight self.left = None self.right = None # 构造哈夫曼 def build_huffman_tree(values, weights): nodes = [Node(value, weight) for value, weight in zip(values, weights)] while len(nodes) > 1: nodes = sorted(nodes, key=lambda x: x.weight) left = nodes.pop(0) right = nodes.pop(0) parent = Node(None, left.weight + right.weight) parent.left = left parent.right = right nodes.append(parent) return nodes[0] # 测试代码 values = ['A', 'B', 'C', 'D'] weights = [1, 2, 3, 4] root = build_huffman_tree(values, weights) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值