论文网
English Papers
万事OK网
发表论文
 
 首页 > IT文章 > 程序设计 >
采用链式存储结构构造哈夫曼树

[科技论文网] http://www.scipapers.com    2007-12-01  

    采用链式存储结构构造哈夫曼树

    作者:颜清国   

    /************************************************************************
    *
    * 文件名:HFtree.c
    *
    * 文件描述:本程序给出哈夫曼树的链式构造法和哈夫曼的编码
    *           在turboc 2.0 调试通过,在其他编译环境下请把
    *           gotoxy和getch两个函数重写
    *
    * 创建人: 颜清国   2006年5月4日
    * 说明: 
    *            采用链式存储结构构造哈夫曼树,可以很方便的将树的各种操作加
    *            到哈夫曼树上来,包括其编码
    ************************************************************************/
    
    #include "stdio.h"
    #include "stdlib.h"
    #include "conio.h"
    
    #define LEN sizeof(HFtree) /*HFtree结构体大小*/
    
    /*哈夫曼树结构体*/
    typedef struct tagHFtree
    {
    	char data;            /*结点数据,以后用到*/
    	double weight;         /*结点的权重*/
    	struct tagHFtree* parent; /*双亲结点*/
    	struct tagHFtree* lchild; /*左孩子*/
    	struct tagHFtree* rchild; /*右孩子*/
    	struct tagHFtree* next;    /*指向下一个结点*/
    }HFtree;
    
    /*哈夫曼编码结构体*/
    struct tagHFcode
    {
     char data;           /*结点数据*/
     double weight;       /*结点的权重*/     
     int code[20];            /*存放编码*/
     int top;             /*编码的位数*/
    };
    
    /***********************************************
     创建哈夫曼树核心部分
    ************************************************/
    void Create(HFtree**head)
    {
    	HFtree*lp,*temp,*lchild,*rchild;
    	while((*head)->next->next!=NULL)
    	{
    		lchild=rchild=(*head);   /*每次从头开始查找,这里(*head)的weight没用,*/
                                              /*刚好用来放左右孩子*/           
                    temp=(*head)->next;    /*最初的的weight*/
    		lchild->weight=rchild->weight=3.14e+38;  /*重新找时每次将左右孩子的weight置为最大*/
    		lp=(HFtree*)malloc(LEN);
                    lp->parent=NULL;
    		while(temp!=NULL)            /*查找最小的作为左孩子*/
    		{
    			if(lchild->weight > temp->weight)
    			{
    				lchild=temp;
    			}
    			temp=temp->next;
    		}
    		temp=(*head)->next;          /*重新定位到(*head)->next*/
    		while(temp!=NULL)            /*查找次小的作为右孩子*/
    		{                 /*注意这里不要用temp->weight!=lchild->weigh*/
    			if(rchild->weight > temp->weight && temp!=lchild) 
    			{
    				rchild=temp;
    			}
    			temp=temp->next;
    		}
    		
    		lp->lchild=lchild;                        /*对LP及其左右孩子附值*/
    		lp->rchild=rchild;                        
    		lchild->parent = rchild->parent =lp;
    		lp->weight=lchild->weight + rchild->weight;  /*将左右孩子的权值相加*/
    		lp->next=(*head)->next;                /*将LP插到表头*/
    		(*head)->next=lp;                      /*每次让(*head)->next指向新加进来的结点*/
    		temp=lp;                               /*将lp和temp两个指针重新定位,用来遍历链表*/
    		lp=lp->next;
    		while(lp!=NULL)                        /*将左右孩子从待创建的链表系列中删除*/
    		{
    			if(lp==lchild || lp==rchild)
    			{
    				temp->next=lp->next;
    				lp->next=NULL;
    			}
    			else
    				temp=lp;
    			lp=temp->next;
    			
    		}
    	}
    }
    
    
    /***********************************************
    创建哈夫曼树
    ************************************************/
    void CreateHFtree(double nodewei[],int n,HFtree**head)
    {
    	int i=0;
    	HFtree*lp=(HFtree*)malloc(LEN),*rear;
    	(*head)=(HFtree*)malloc(LEN);
            (*head)->parent=NULL;
    	(*head)->next=rear=lp;                                 /*head头结点,保证指向剩余的结点链*/
    	lp->parent=lp->lchild=lp->rchild=lp->next=NULL;
    	while(iweight=nodewei[i++];
    		rear->next=lp;                          /*第一次REAR指向自身*/
    		rear=lp;
    		lp=(HFtree*)malloc(LEN);
    		lp->parent=lp->lchild=lp->rchild=lp->next=NULL;
    	}
    	free(lp);                                    /*释放最后一个结点*/
    	Create(head);                               /*创建一棵树,树的头结点为(*HEAD)->next*/
    }
    
    /*************************************************
     由先序遍历求出哈夫曼树求出哈夫曼编码
    **************************************************/
    void HFcoding(HFtree*root,HFtree*temp,struct tagHFcode HFcode[],int*leaftop)
    {
     if(root!=NULL)
     {
      if(root->lchild==NULL && root->rchild==NULL)    /*是叶子结点,求得编码*/
      {
       temp=root;
       HFcode[(*leaftop)].top=0;
       HFcode[(*leaftop)].weight=root->weight;
       HFcode[(*leaftop)].data=root->data;
       while(temp->parent!=NULL)
       {
        if(temp->parent->lchild==temp)                   
        HFcode[(*leaftop)].code[HFcode[(*leaftop)].top]=0;
        else
        HFcode[(*leaftop)].code[HFcode[(*leaftop)].top]=1;
        HFcode[(*leaftop)].top++;
        temp=temp->parent;
       }
       (*leaftop)++;
      }
      HFcoding(root->lchild,temp,HFcode,leaftop);
      HFcoding(root->rchild,temp,HFcode,leaftop);
    }
    }
    
    /***********************************************
     输出求得的哈夫曼编码
    ************************************************/
    void OutCoding(struct tagHFcode HFcode[],int leaftop)
    {
     int i=0,j=0;
              for(;i<leaftop;i++)
              {
                     printf("%.1f :",HFcode[i].weight);
                     j=HFcode[i].top-1;
                     while(j>=0 )
                     {
                      printf("%d",HFcode[i].code[j]);
                      j--;
                     }
                     printf("\n");
              }
    }
    /********************************************
    用括号表示法输出树
    **********************************************/
    void OutTree(HFtree *root)
    {
    	if(root != NULL)
    	{
    		printf("%.1f",root->weight);       /*先输出根结点*/
    		if(root->lchild != NULL || root->rchild != NULL)
    		{
    			printf("(");
    			OutTree(root->lchild);        /*处理左子树*/
    			if(root->rchild != NULL)
    			{
    				printf(",");
    			}
    			OutTree(root->rchild);         /*处理右子树*/
    			printf(")");
    		}
    	}
    }
    
    /*****************************************************************
     用树形表示法输出树
    ******************************************************************/
    void DispTree(HFtree *root,int x,int y,int n)     /*n用来控制第一层树的高度*/
    {
     int i=0;
     if(root !=NULL)
      {
        gotoxy(x,y);                               /*到相应结点输出*/
        printf("%.1f",root->weight);
        if(root->lchild != NULL)                  /*处理左子树,这里只有第一次N为可变的,*/
        {
           i=1;                                   /*为的是能够输出整棵树,而不会被覆盖,*/
           while(ilchild,x-n,y+n,2);       /*递归处理左子树*/
         }
         if(root->rchild != NULL)
        {
           i=1;
           while(irchild,x+n,y+n,2);       /*递归处理右子树*/
         }
       }
    }
     
    /*****************************************************************
     主函数入口
    ******************************************************************/
    void main()
    {
            double nodewei[20];
            struct tagHFcode HFcode[20];
            int leaftop=0,i=0;
            HFtree*temp=NULL;
    	HFtree*head;
            textbackground(1);
            textcolor(2);
            clrscr();
            printf("the HFtree and HFcoding demo\r\n");
            printf("Input the leafnode weight:");
            scanf("%lf",&nodewei[i]);
            while(nodewei[i++]!=0.0)/*接收数据,以0结尾*/
                    scanf("%lf",&nodewei[i]);
            CreateHFtree(nodewei,i-1,&head);  /*根据接收的数据创建*/
            printf("HFtree:");
    	OutTree(head->next);              /*输出哈夫曼树括号表示法*/
            HFcoding(head->next,temp,HFcode,&leaftop);  /*根据哈夫曼树,求出哈夫曼编码*/
            printf("\nthe HFcoding is:\n");
            OutCoding(HFcode,leaftop);        /*输出哈夫曼编码*/
            DispTree(head->next,30,10,6);     /*用树形表示法输出树*/
            getch();
    }
    
        来源:

声明:本文由网友推荐或作者提交,版权归原作者所有,刊登此文仅为传播知识,展示研究成果,提高文章引用率。未经原作者授权,禁止用于任何形式的商业行为。科技论文网倡导尊重知识、尊重劳动、保护原创、知识共享。由于部分论文文章来于网络,文章作者不祥,请相关的原创作者与我们联系,以便加上您的署名。

  
采用链式存储结构构造哈夫曼树
下面没有链接了     链表反转的两种实现方法
最新论文
·[程序设计]采用链式存储结构构造哈夫曼树
·[程序设计]链表反转的两种实现方法
·[程序设计]数据结构(C语言):迷宫问题
·[程序设计]"S/P先生数学谜题"算法分析及源代码
·[程序设计]单源最短路径bellman-ford算法
·[程序设计]前序遍历二叉树
·[程序设计]哈夫曼树的构造方法与原理
·[程序设计]排列组合算法
·[程序设计]走迷宫程序
·[程序设计]红黑树分析和实现
 
 

搜索论文

Google
论文分类

论文网 论文发表网 论文 免费论文网 找论文网 毕业论文 中国论文网 英语论文 百度论文 聘教网 易搜
 免费发布论文    中国论文网 2008版权所有  业务联系:pinjiao@126.com