数据结构-----哈夫曼树的构造以及遍历

/*
根据Huffman树的构造原理进行构造  ...
哈夫曼树在编码压缩的领域有很好的应用,利用Huffman进行编码可以保证数据传输
的无二义性 。
但是要注意的是 对于出现频率大的数据我们应该尽量放在离根节点近的地方进行编码 ,
出现频率小的数据我们可以放在距离根节点小的地方。
这样可以提高数据的传输效率 。
*/
#include "stdio.h"
#include "malloc.h" 

///节点声明
typedef struct  node{
    node *lChild ;
	node *rChild ;
	int data ;//权值
}TreeNode ;
TreeNode * CreateHuffmanTree(int a[],int n)  ; //数组a表示权的数组  n是个数
void  FindLittle(int *x1,int *x2 ,TreeNode**pArr,int n)  ; //查找出2个权值最小的节点的下标 

TreeNode * CreateHuffmanTree(int a[],int n)   //数组a表示权的数组  n是个数
{
	TreeNode**pArr=(TreeNode**)malloc(sizeof(TreeNode*)*n);  //动态产生指针数组
	TreeNode*p =NULL;//用于返回哈夫曼树的根节点的指针
	int k1,k2 ;  //k1代表最小权  k2代表次小权    用于做为 FindLittle的参数查找最小权下标
	for(int i=0;i<n;i++)
	{
		pArr[i]=new TreeNode ;    //为节点指针数组动态分配指向的对象
		pArr[i]->data=a[i]  ;
		pArr[i]->lChild=pArr[i]->rChild=NULL ;//初始化每个节点的左右节点都是空
	}

	///因为哈夫曼树是循环的从节点数组中找出权值最小的两个节点进行组合 并从数组中删除这两个节点,并把合并后的节点添加到数组中。
	for(i=0;i<n-1;i++) //因为最后还剩下一个节点所以就会挑选n-1次
	{
		FindLittle(&k1,&k2,pArr,n) ; //查找2个最小权节点下标
		p=new TreeNode;   //循环组合最后的p指向的节点便是最终的pRoot
		p->data=pArr[k1]->data+pArr[k2]->data  ;
		p->lChild=pArr[k1] ;
		p->rChild=pArr[k2] ;  

		pArr[k1]=p    ;   //将合并后的新节点赋值给pArr最小的那个下标
		pArr[k2]=NULL ;   // 次下标设置NULL, k1和k2也可以反过来这个具体我们自己定

	}
	free(pArr) ;//释放指针数组
	return p;
}

void  FindLittle(int *x1,int *x2 ,TreeNode**pArr,int n)  //查找出2个权值最小的节点的下标
{
	int  k1,k2;  //保存权最小的两个节点下标
	k1=-1 ; //表示没有找到数据
	for(int i=0;i<n;i++)    //找出其中的前两个元素不为NULL的下标
	{
		if(pArr[i]!=NULL&&k1==-1)
		{
			k1=i ;     //第一个下标
			continue ;
		}
		if(pArr[i]!=NULL)
		{
			k2=i ;
			break;//找到第二个下标退出循环
		}
	}

	////// 最小权的2个下标的搜索实现//////////
	for(i=k2;i<n;i++) //我们是先获取k1  后获取k2所以一开始 一定是从k2开始循环的
	{
	if(pArr[i]!=NULL)
	{
        if(pArr[i]->data<pArr[k1]->data )  //如果下标k1的权 小于当前下标的元素的权
		{
			k2=k1;  //此时还是k1<k2满足我们返回的结果
			k1=i ;
		}
		else if(pArr[i]->data<pArr[k2]->data)
		{
			k2=i ;
		}

	}
	}
	*x1=k1  ;
	*x2=k2  ;
}

///哈夫曼树的先序遍历
void PreHufOrder(TreeNode*p)   //先序遍历
{
	if(p!=NULL)
	{
		printf("%d ",p->data) ;
		PreHufOrder(p->lChild) ;
		PreHufOrder(p->rChild) ;
	}
}

//中序遍历
void InHufOrder(TreeNode*p)
{
	   if(p!=NULL)
	   {
		   InHufOrder(p->lChild) ;
		   printf("%d ",p->data) ;
		   InHufOrder(p->rChild) ;
	   }
}
//后续遍历
void PostHufOrder(TreeNode*p)
{
	if(p!=NULL)
	{
		InHufOrder(p->lChild) ;
		InHufOrder(p->rChild) ;
		printf("%d ",p->data) ;
	}
}
//清空树
void ClearHufTree(TreeNode*p)
{
	if(p!=NULL)
	{
		ClearHufTree(p->lChild) ;
		ClearHufTree(p->rChild) ;
		delete p ;
	}
}

int main()
{
    int a[]={3,5,3,8,7,9,4,2,4,5,6,3,2,3} ;  //权值
    TreeNode*p=::CreateHuffmanTree(a,sizeof(a)/sizeof(int)) ; //创建huffman树
	printf("Huffman前序遍历:\n") ;
    PreHufOrder(p) ;  //前序遍历huffmanTree
	printf("\n");
	printf("Huffman后序遍历:\n") ;
	PostHufOrder(p) ;//后序遍历
	printf("\n");
	printf("Huffman中序遍历:\n") ;
	InHufOrder(p) ;//中序遍历
	printf("\n");
	ClearHufTree(p) ;//清空树
	return  0 ;
}
时间: 2024-08-18 07:12:52

数据结构-----哈夫曼树的构造以及遍历的相关文章

c++ 数据结构-一个程序,哈夫曼树的构造遍历打印,编码解码,缺少遍历和打印

问题描述 一个程序,哈夫曼树的构造遍历打印,编码解码,缺少遍历和打印 #include #include /* 数组头文件 / #include #define MAX 999 / 定义长度 / typedef struct{ / 定义哈夫曼编码的结构数组 / char data; int weight; / 定义权值 / int parent; int lchild; int rchild; }huffmannode; typedef struct{ / 定义保存哈夫曼结构体 / char b

Java实现哈夫曼树的构造

哈夫曼树的内容这里不作解释,请自己搜索.下面给出哈夫曼树构造过程的 Java 实现. 结点类: 1./** 2. * 二叉树节点 3. */ 4.public class Node implements Comparable { 5. 6. private int value; 7. 8. private Node leftChild; 9. 10. private Node rightChild; 11. 12. public Node(int value) { 13. this.value

数据结构哈夫曼树代码怎么写

问题描述 数据结构哈夫曼树代码怎么写 哈夫曼树:输入一串只包含abcdefg8种字符的字符串,统计每种字符出现的次数,并据此创建相应的哈夫曼树. 这怎么写 解决方案 统计字符个数这个简单,你创建一个数组,将每个字符的ascii-'a',得到下标,对应下标+1http://blog.csdn.net/yaoowei2012/article/details/18180769 解决方案二: http://www.cnblogs.com/shiyangxt/archive/2008/12/05/1348

C++实现哈夫曼树简单创建与遍历的方法_C 语言

本文以实例形式讲述了C++实现哈夫曼树简单创建与遍历的方法,比较经典的C++算法. 本例实现的功能为:给定n个带权的节点,如何构造一棵n个带有给定权值的叶节点的二叉树,使其带全路径长度WPL最小. 据此构造出最优树算法如下: 哈夫曼算法: 1. 将n个权值分别为w1,w2,w3,....wn-1,wn的节点按权值递增排序,将每个权值作为一棵二叉树.构成n棵二叉树森林F={T1,T2,T3,T4,...Tn},其中每个二叉树都只有一个权值,其左右字数为空 2. 在森林F中选取根节点权值最小二叉树,

数据结构——赫夫曼树

1 基本概念 赫夫曼树(Huffman Tree)又称为最优树,是一类带权路径长度最短的树.本文仅讨论最优二叉树. 树的路径长度是指从树根到树中其余各个结点的路径长度之和.对具有n个结点的二叉树而言,完全二叉树具有最短的树的路径长度. 若在二叉树中,树叶结点带有权值,则有:结点的带权路径长度定义为从树根到该结点之间的路径长度与该结点上所带权值之积. 若树中有n个树叶结点,且每个树叶结点均带有权值,则有:树的带权路径长度定义为树中所有树叶结点的带权路径长度之和,可记为: 有时,也将树的路径长度称为

数据结构-哈夫曼树运行错误 但调试却正确 一直找不成错误

问题描述 哈夫曼树运行错误 但调试却正确 一直找不成错误 估计问题是出在HuffmanCoding 但怎么都找不出来 #include "stdio.h" #include "stdlib.h" #include "string.h" char alphabet[]={'A','B','C','D'}; typedef struct { int weight; //权值 int parent; //父节点序号 int left ; int rig

数据结构-构造哈夫曼树的小问题

问题描述 构造哈夫曼树的小问题 完整程序在这里:http://wenku.baidu.com/view/dde580a9376baf1ffc4fadbf template class HfmTree :public BinaryTree { public: operator T()const { return weight; } T getW(){ return weight; } void putW(const T& x){ weight = x; } void SetNull(){ root

哈夫曼树(三) Java详解

哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树. 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树.这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答. (01) 路径和路径长度 定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径.通路中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1. 例子:100和80的路径长度是

哈夫曼树(二) C++详解

哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树. 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树.这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答. (01) 路径和路径长度 定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径.通路中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1. 例子:100和80的路径长度是