haffmanTree(哈夫曼树)的相关操作 + 两种遍历哈弗曼算法+ 无递归遍历+ 叶子节点遍历
2013-05-26 15:30
465 查看
#include<iostream> using namespace std ; typedef struct node//节点的信息 { int weight ; int parent , lchild , rchild ; }node , *HuffmanTree; typedef char * * HuffmanCode ; /*按升序排*/ int cmp(const void *a , const void *b) { return ((HuffmanTree)a)->weight - ((HuffmanTree)b)->weight ; } /*在HT[1....i-1]中选出parent 为0 ,且weight最小的两个数,返回他们的序号*/ void Select(HuffmanTree HT , int n , int &s1 , int &s2 ) { qsort(HT,n,sizeof(HT[1]), cmp ); for(int i = 1 ; i <= n ; i ++) { if(HT[i].parent == 0 ) { s1 = i ; i ++ ; break; } } for( ; i <= n ; i ++) { if(HT[i].parent == 0 ) { s2 = i ; break; } } return ; } /*创建哈夫曼树和求得哈弗曼编码*/ void Hffmancode(HuffmanTree &HT , HuffmanCode &HC , int *w , int n ) { if(n < 1 ) return ; int i,m = 2*n - 1 ; //n节点的树有2*n-1个节点 HT = (HuffmanTree ) malloc((m+1)*sizeof(node)); HuffmanTree p ; for( i = 0 ,p = HT ; i <= n ; i ++,p++ , w ++ ) //初始化叶子节点 { p->weight = *w ; p->parent = 0 ; p->lchild = 0 ; p->rchild = 0 ; } for(; i <= m ; p++,i++) //初始化剩下的节点 { p->weight = 0 ; p->parent = 0 ; p->lchild = 0 ; p->rchild = 0 ; } for( i = n+1 ; i<= m ; i ++) { int s1 , s2 ; /*在HT[1....i-1]中选出parent 为0 ,且weight最小的两个数,返回他们的序号*/ Select(HT , i - 1 , s1 , s2 ); HT[s1].parent = i ; HT[s2].parent = i ; HT[i].lchild = s1 ; HT[i].rchild = s2 ; HT[i].weight = HT[s1].weight + HT[s2].weight ; } /*从叶子节点反序遍历整颗树,并求得哈弗编码*/ HC = (HuffmanCode )malloc((n+1)*sizeof(node)) ; char *cd ; cd = (char *)malloc(n*sizeof(char)) ; cd[n-1] = '\0' ; for( i= 1; i <= n ; i++) { int start = n-1 , c , f ; for( c = i , f = HT[i].parent ; f!= 0 ; c = f , f = HT[f].parent ) if(HT[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1' ; HC[i] = (char *)malloc((n-start)*sizeof(char) ) ; strcpy(HC[i] , &cd[start]); } free(cd); } /*无递归从根节点求哈弗曼编码*/ void Hfffin(HuffmanTree HT, HuffmanCode &hc,int n , int m) { hc = (HuffmanCode)malloc((m+1)*sizeof(char *)); int p = m ; int len = 0 ; for(int i = 1; i <= m ; i ++) HT[i].weight = 0 ; char cd[10] ; while(p>0) { if(HT[p].weight == 0 ) { HT[p].weight = 1; if(HT[p].lchild != 0 ) { p = HT[p].lchild ; cd[len ++] = '0' ; } else if(HT[p].rchild == 0 ) { hc[p] = (char *)malloc((len + 1)*sizeof(char)); cd[len] = '\0' ; strcpy(hc[p],cd); } } else if(HT[p].weight == 1) { HT[p].weight = 2; if(HT[p].rchild != 0 ) { p = HT[p].rchild ; cd[len++] = '1'; } } else { HT[p].weight = 0 ; p = HT[p].parent ; --len ; } } } int main(void) { int w[100] ; for(int i = 0 ; i < 10 ; i ++) w[i] = i + 1 ; HuffmanTree HT ; HuffmanCode HC ; cout<<"建立哈夫曼树,并求得哈弗曼编码"<<endl; Hffmancode(HT , HC , w , 10); for( i = 1 ; i <= 10 ; i++) cout<<i<<"的哈弗编码是:"<< HC[i]<<endl; cout<<endl; cout<<"无递归遍历整颗树"<<endl; HuffmanCode hc ; Hfffin(HT ,hc,10 , 19) ; for( i = 1 ; i <= 10 ; i++) cout<<i<<"的哈弗编码是:"<< HC[i]<<endl; return 0; }
相关文章推荐
- 二叉树的递归遍历非递归遍历以及其他二叉树的相关操作实现(数据结构)
- linux文件与目录操作相关API及递归遍历目录
- 二叉树的创建、相关操作、递归和非递归式实现三种遍历
- 用java实现二叉树相关操作(前序建树,前中后递归非递归遍历,层序遍历)
- 二叉搜索树的相关操作:插入节点,删除节点,排序,查找,最大值,最小值,前序,中序,后序遍历(主要用到递归的方法)
- 二叉树相关操作(前序遍历,中序遍历,后序遍历,层次序遍历等)递归和非递归实现
- 链表相关操作二(两种遍历方式)
- 数据结构五:二叉树的递归遍历,二叉树的叶子节点个数,二叉树的拷贝操作基础学习
- 不疯魔,不成活!——二叉树的创建、遍历(递归实现)等操作。
- 二叉树的两种遍历方式[递归遍历][非递归遍历]
- 接口回调;new FileFilter(接口)重写accept递归深度遍历后缀名文件;File[]和stringbuffer两种方法
- IOS 递归简单使用及相关操作
- java 遍历递归操作(改名) 文件/文件夹
- 二叉树建立与遍历递归操作c++实现
- c++模板实现二叉树,线索化,线索化遍历,非递归遍历及一些基本操作
- map相关操作:map遍历,map转换为list
- 有关二叉树的相关实现:建树,遍历(递归与非递归实现)
- Java遍历文件夹的两种方法(非递归和递归) .
- 二叉树实现(包括遍历等各种操作,递归与非递归)
- 黑马程序员_学习日记53_625三层项目(FTP相关操作、递归TreeView、三层结构)