typedef struct BiNode
{
TElemType data;
struct BiNode *Lchild,*Rchild;
}BiNode,*BiTree;
status PreOrderTraverse(BiTree T)//递归
{
if(T==NULL)
return OK;
else
{
visit(T);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
status InOrderTraverse(BiTree T)//递归
{
if(T==NULL)
return OK;
else
{
InOrderTraverse(T->lchild);
visit(T);
InOrderTraverse(T->rchild);
}
}
status InOrderTraverse(BiTree T)//非递归
{
BiTree p;InitStack(S);p=T;
while(p||!StackEmpty(S))
{
if(p)
{
Push(S,p);
p=p->lchild;
}
else
{
Pop(S,q);
printf("%c",q->data);
p=q->rchild;
}
}
return OK;
}
status PostOrderTraverse(BiTree T)//递归
{
if(T==NULL)
return OK;
else
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
visit(T);
}
}
typedef struct
{
BTNode data[MaxSize];
int front,rear;
}SqQueue;
void LevelOrder(BTNode *b)
{
BTNode *p;SqQueue *qu;
InitQueue(qu);
enQueue(qu,b);
while(!QueueEmpty(qu))
{
deQueue(qu,p);
if(p->lchild!=NULL)
enQueue(qu,p->lchild);
if(p->rchild!=NULL)
enQueue(qu,p->rchild);
}
}
status CreateBiTree(BiTree &T)
{
scanf(&ch);
if(ch=="#")
T=NULL;
else
{
if(!(T=(BiTNode*)malloc(sizeof(BitNode))))
exit(OVERFLOW);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
int Copy(BiTree T,BiTree &NewT)
{
if(T==NULL)
{
NewT=NULL;
return 0;
}
else
{
NewT=new BiTNode;
NewT->data=T->data;
Copy(T->lChild,NewT->lchild);
Copy(T->rChild,NewT->rchild);
}
}
int Depth(BiTree T)
{
if(T==NULL)
return 0;
else
{
m=Depth(T->lChild);
n=Depth(T->rChild);
if(m>n)
return(m+1);
else
return(n+1);
}
}
int NodeCount(BiTree T)
{
if(T=NULL)
return 0;
else
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
int LeadCount(BiTree T)
{
if(T=NULL)
return 0;
if(T->lchild==NULL&&T->rchild==NULL)
return 1;
else
return LeafCount(T->lchild)+LeafCount(T->rchild);
}
//结构体函数
typedef struct BiThrNode
{
int data;
int ltag,rtag;
struct BiThrNode *lchild,rchild;
}BiThrNode,*BiThrTree;
ypedef struct PTNode
{
TElemType data;
int parent;
}PTNode;
#define MAX_TREE_SIZE 100
typedef struct
{
PTNode nodes[MAX_TREE_SIZE];
int r,n;
}PTree;
typedef struct CTNode //孩子结点结构
{
int child;
struct CTNode *next;
}*ChildPtr;
typedef struct //双亲结点结构
{
TElemType data;
ChildPtr firstchild;
}CTBox;
typedef struct //树结构
{
CTBox nodes[MAX_TREE_SIZE];
int n,r;
}CTree;
typedef struct CSNode
{
ElemType data;
struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;
哈夫曼树的结点的度数为0或2,没有度为1的结点
包含n个叶子结点的哈夫曼树中共有2n-1个结点
包含n棵树的森林要经过n-1次合并才能形成哈夫曼树,共产生n-1个新结点
采用顺序存储结构——一堆结构数组
结点类型定义
typedef struct
{
int weight;
int parent,lch,rch;
}HTNode,*HuffmanTree;
构造哈夫曼树
void CreatHuffmanTree(HuffmanTree HT,int n)
{
if(n<=1)
return;
m=2*n-1;
HT=new HTNode[m+1];
for(i=1;i<=m;++i)
{
HT[i].lch=0;HT[i].rch=0;HT[i].parent=0;
}
for(i=1;i<=n;++i)
scanf("s",HT[i].weight);
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// 初始化结束
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
for(i=n+1;i<=m;i++)
{
select(HT,i-1,s1,s2);
HT[s1].parent=i; HT[s2].parent=i;
HT[i].lch=s1; HT[i].rch=s2;
HT[i]weight=HT[s1].weight+HT[s2].weight;
}
}
将待传字符转换成二进制的字符串
A——00 B——01 C——10 D——11
若将编码设计为长度不等的二进制编码,即让待传字符串中出现次数较多的字符采用尽可能短的编码,则转换的二进制字符串便可能减少
关键:要设计长度不等的编码,则必须使任一字符的编码都不是另一个字符的编码的前缀——这种编码称做前缀编码
哈夫曼编码
统计字符集中每个字符在电文中出现的平均概率(概率越大,要求编码越短)
利用哈夫曼树的特点:权越大的叶子离根越近;将每个字符的概率值作为权值,构造哈夫曼树。则概率越大的结点,路径越短
在哈夫曼树的每个分支上标上0或1:
结点的左分支标0,右分支标1
把从根到每个叶子的路径上的标号连接起来,作为该叶子代表的字符的编码
性质:哈夫曼编码是前缀码;哈夫曼编码是最优前缀码
void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{
HC=new char *[n+1];//分配n个字符编码的头指针矢量
cd=new char[n];//分配临时存放编码的动态数组空间
cd[n-1]='\0';//编码结束符
for(i=1;i<=n;i++)//逐个字符求哈夫曼编码
{
start=n-1;c=i;f=HT[i].parant;
while(f!=0)//从叶子结点开始向上回溯,直到根结点
{
start--;//回溯一次start向前指一个位置
if(HT[f].lchild==c)
cd[start]='0';//结点c是f的左孩子,则生成代码0
else
cd=[start]='1';//结点c是f的右孩子,则生成代码1
c=f;f=HT[f].parant;//继续向上回溯
}//求出第i个字符的编码
HC[i]=new char[n-start];//为第i个字符串编码分配空间
strcpy(HC[i],&cd[start]);//将求得的编码从临时空间cd复制到HC的当前行中
}
delete cd;//释放临时空间
}