4.7判定树和哈夫曼树

#include "stdafx.h"
#include 
<iostream.h>
#include 
<malloc.h>

int const ELEMENTCOUNT=5;                            //判断条件的个数,即初始根节点的数量
struct node
{
    
float wt;                                        //权值
    int parent,lchild,rchild;                        //双亲的下标,左子树下标,右子树下标
    char data;                                        //该节点的值,这是我加的,方便我在显示的时候验证是否正确
}
;

typedef node hftree[
2*ELEMENTCOUNT-1];                //保存所有Huffman树的节点的数组,需要2N-1个元素

//count:初始根结点的数量,WT[]保存各节点的权值,tree为huffman树
//算法中我没有使用书上的变量名,说实话,书上变量名乱起(i,j,k,x,y,m,n.),我看明白了算法后才知道各个变量的意义.
void huffman(int count,float WT[],hftree & tree)
{
    
float minWT1=0,minWT2=0;                            //保存第一小和第二小权值
    int minE1=0,minE2=0;                                //保存第一小和第二小的根的在数组中的下标
    int i=0,j=0;
    
//初始化树
    for(i=0;i<2*ELEMENTCOUNT-1;i++)
    
{
        tree[i].parent
=-1;
        tree[i].lchild
=-1;
        tree[i].rchild
=-1;
        
if (i<count)
        
{
            tree[i].wt
=WT[i];
        }

        
else
        
{
            tree[i].wt
=0;
            tree[i].data
='N';                        //N为新生成的结点
        }

    }

    
//开始生成huffman树
    for(i=0;i<ELEMENTCOUNT-1;i++)                    //因为总结点数为2*ELEMENTCOUNT-1,而生成的新结点数为总结点数-初始根结点数,即:2*ELEMENTCOUNT-1-ELEMENTCOUNT=ELEMENTCOUNT-1
    {
        minWT1
=minWT2=1;                            //1为最大权值
        minE1=minE2=0;
        
//循环找到第1小和第2小的节点,并记住其权值
        for(j=0;j<ELEMENTCOUNT+i;j++)                //j<ELEMENTCOUNT+i意味着,每次都从0循环至上次新增的节点,用以寻找剩下的根结点
        {
            
if (tree[j].parent==-1 && tree[j].wt<minWT1)
            
{
                minE2
=minE1;
                minE1
=j;

                minWT2
=minWT1;
                minWT1
=tree[j].wt;
            }

            
else if (tree[j].parent==-1 && tree[j].wt<minWT2)
            
{
                minE2
=j;
                minWT2
=tree[j].wt;
            }

        }

        
//开始生成新的结点,并修改原父结点的下标
        tree[ELEMENTCOUNT+i].parent=-1;
        tree[ELEMENTCOUNT
+i].wt=minWT1+minWT2;
            
//此处其左子树与右子树对应可以随意,因为其结点肯定要做为其它结点的子结点
        tree[ELEMENTCOUNT+i].lchild=minE1;
        tree[ELEMENTCOUNT
+i].rchild=minE2;
            
//修改原根结点的父结点
        tree[minE1].parent=tree[minE2].parent=ELEMENTCOUNT+i;
    }

}


//采用栈的方式消除递归
void Display(hftree & tree)
{
    
int stack[100];
    
int top=0;
    
//根入栈
    stack[top]=2*ELEMENTCOUNT-2;
    
while(top!=-1)
    
{
        
int index=stack[top];
        top
--;
        
while(index!=-1)
        
{
            cout
<<"结点的Data为:"<<tree[index].data<<","<<"结点的权值为:"<<tree[index].wt<<endl;
            
int left=-1,right=-1;
            
//寻找左节点和右节点
            for(int i=0;i<2*ELEMENTCOUNT-1;i++)
            
{
                
if (tree[i].parent==index)
                
{
                    
if (left==-1)
                    
{
                        left
=i;
                    }

                    
else
                    
{
                        right
=i;
                        
break;
                    }

                }

            }

            
if (left==-1 && right==-1)
            
{
                index
=-1;
            }

            
else
            
{
                index
=left;
                top
++;
                stack[top]
=right;
            }

        }

    }

}


int main(int argc, char* argv[])
{
    hftree tree;
    
float WT[ELEMENTCOUNT];

    tree[
0].data='A';
    WT[
0]=0.1f;
    tree[
1].data='B';
    WT[
1]=0.2f;
    tree[
2].data='C';
    WT[
2]=0.3f;
    tree[
3].data='D';
    WT[
3]=0.2f;
    tree[
4].data='E';
    WT[
4]=0.2f;

    huffman(ELEMENTCOUNT,WT,tree);
    Display(tree);

    
return 0;
}

    
posted @ 2007-07-14 15:06  吴东雷  阅读(590)  评论(0编辑  收藏  举报