树的遍历算法(完美C语言)
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
HT[k].Lchild=p1 ; HT[k].Rchild=p2 ;
HT[k].weight=w1+w2 ;
HT[p1].Parent=k ; HT[p2].Parent=k ;
}
}
Huffman 编码算法
根据出现频度(权值)Weight,对叶子结点的 Huffman 编码有两种方式: ① 从叶子结点到根逆向处理,求得每个叶子结点对应字符的 Huffman 编码。
} HTNode ;
void Create_Huffman(unsigned n, HTNode HT[ ], unsigned m)
/* 创建一棵叶子结点数为 n 的 Huffman 树 */
{
unsigned int w ; int k , j ;
for (k=1 ; k<m ; k++)
{
if (k<=n)
{ if (T!=NULL)
{ PostorderTraverse(T->Lchild) ;
PostorderTraverse(T->Rchild) ;
visit(T->data) ;
Hale Waihona Puke /* 访问根结点 */} } /*图 6-8(a) 的二叉树,输出的次序是: cgefdba */
非递归遍历: 设 T 是指向根结点的指针变量,非递归算法是: 若二叉树为空,则返回;否则,令 p=T; ⑴ 第一次经过根结点 p,不访问:
----------------------------------------------------------------------------------------------------------------------
#define MAX_NODE 50
void PreorderTraverse( BTNode *T)
---------------------------------------------------------------------------------------------------------------------define MAX_NODE 50 void PostorderTraverse( BTNode *T) {
{
BTNode *Stack[MAX_NODE] ,*p=T ;
int top=0 , bool=1 ; if (T==NULL) printf(“ Binary Tree is Empty!\n”) ;
else
{
do
{
while (p!=NULL)
{
stack[++top]=p ;
p=p->Lchild ;
Huffman 树的生成---算法实现:
结点类型定义:
#define MAX_NODE 200 /* Max_Node>2n-1 */
typedef struct
{ unsigned int Weight ;
/* 权值域 */
unsinged int Parent , Lchild , Rchild ;
} /* 初始化向量 HT */
for (k=n+1; k<m ; k++)
{
unsigned w1=32767 , w2=w1 ; /* w1 , w2 分别保存权值最小的两个权值 */
int p1=0 , p2=0 ;
/* p1 , p2 保存两个最小权值的下标 */
for (j=1 ; j<=k-1 ; j++)
}
if (top==0)
bool=0 ;
else
{
p=stack[top] ; top-- ;
visit( p->data ) ; p=p->Rchild ;
}
}
while (bool!=0) ; } }
二叉树的后序遍历:
后序遍历的递归算法:
void PostorderTraverse(BTNode *T)
{
printf(“\n Please Input Weight : w=?”);
scanf(“%d”, &w) ;HT[k].weight=w ;
}
/* 输入时,所有叶子结点都有权值 */
else HT[k].weight=0; /* 非叶子结点没有权值 */
HT[k].Parent=HT[k].Lchild=HT[k].Rchild=0 ;
if (top==0) bool=0 ; else if (S2[top]==0) {
p=S1[top]->Rchild ; S2[top]=1 ; } else { p=S1[top] ; top-- ; visit( p->data ) ; p=NULL ; /* 使循环继续进行而不至于死循环 */ } } while (bool!=0) ; } }
二叉树的先序遍历:
递归算法:
void PreorderTraverse(BTNode *T)
{
if (T!=NULL)
{ visit(T->data) ;
/* 访问根结点 */
PreorderTraverse(T->Lchild) ;
PreorderTraverse(T->Rchild) ;
}
} 非递归遍历:
visit(T->data) ;
/* 访问根结点 */
PreorderTraverse(T->Rchild) ;
}
} 非递归遍历:
设 T 是指向二叉树根结点的指针变量,非递归算法是: 若二叉树为空,则返回;否则,令 p=T ⑴ 若 p 不为空,p 进栈, p=p->Lchild ; ⑵ 否则(即 p 为空),退栈到 p,访问 p 所指向的结点; ⑶ p=p->Rchild ,转(1); 直到栈空为止。
trcpy(HC[k] , &cd[sp]) ;
}
free(cd) ;
}
{
BTNode *Stack[MAX_NODE] ,*p=T, *q ;
int top=0 ;
if (T==NULL) printf(“ Binary Tree is Empty!\n”) ;
else
{
do
{
visit( p-> data ) ;
q=p->Rchild ;
if ( q!=NULL )
BTNode *S1[MAX_NODE] ,*p=T ; int S2[MAX_NODE] , top=0 , bool=1 ; if (T==NULL) printf(“Binary Tree is Empty!\n”) ; else {
do {
while (p!=NULL) {
S1[++top]=p ; S2[top]=0 ; p=p->Lchild ; }
p 进栈 S1 , tag 赋值 0,进栈 S2,p=p->Lchild 。 ⑵ 若 p 不为空,转(1),否则,取状态标志值 tag :
⑶ 若 tag=0:对栈 S1,不访问,不出栈;修改 S2 栈顶元素值(tag 赋值 1) ,取 S1 栈顶元 素的右子树,即 p=S1[top]->Rchild ,转(1); ⑷ 若 tag=1:S1 退栈,访问该结点; 直到栈空为止。
stack[++top]=q ;
p=p->Lchild ;
if (p==NULL) { p=stack[top] ; top-- ; }
}
while (p!=NULL) ;
}
}
二叉树的中序遍历:
递归算法:
void InorderTraverse(BTNode *T)
{
if (T!=NULL)
{
PreorderTraverse(T->Lchild) ;
/* 动态分配求编码的工作空间 */ /* 编码的结束标志 */ /* 逐个求字符的编码 */
{
sp=n ; p=k ; fp=HT[k].parent ; for ( ; fp!=0 ;p=fp , fp=HT[p].parent) /* 从叶子结点到根逆向求编码 */
if (HT[fp].parent==p) cd[--sp]=‘0’ ; else cd[--sp]=‘1’ ; HC[k]=(char *)malloc((n-sp)*sizeof(char)) ; /* 为第 k 个字符分配保存编码的空间
----------------------------------------------------------------------------------------------------------------------
#define MAX_NODE 50
void InorderTraverse( BTNode *T)
设 T 是指向二叉树根结点的指针变量,非递归算法是: 若二叉树为空,则返回;否则,令 p=T; ⑴ 访问 p 所指向的结点; ⑵ q=p->Rchild ,若 q 不为空,则 q 进栈; ⑶ p=p->Lchild ,若 p 不为空,转(1),否则转(4); ⑷ 退栈到 p ,转(1),直到栈空为止。
算法实现
void Huff_coding(unsigned n , Hnode HT[] , unsigned m) /* m 应为 n+1,编码的最大长度 n 加 1 */
{
int k , sp ,fp ;
char *cd , *HC[m] ; cd=(char *)malloc(m*sizeof(char)) ; cd[n]=‘\0’ for (k=1 ; k<n+1 ; k++)
{
if (HT[k].Parent==0) /* 尚未合并 */
{
if (HT[j].Weight<w1)
{
w2=w1 ; p2=p1 ;
w1=HT[j].Weight ; p1=j ;
}
else if (HT[j].Weight<w2)
{
w2=HT[j].Weight ; p2=j ;
}
} /* 找到权值最小的两个值及其下标 */
② 从根结点开始遍历整棵二叉树,求得每个叶子结点对应字符的 Huffman 编码。 由 Huffman 树的生成知,n 个叶子结点的树共有 2n-1 个结点,叶子结点存储在数组
HT 中的下标值为 1∽n。 ① 编码是叶子结点的编码,只需对数组 HT[1…n]的 n 个权值进行编码; ② 每个字符的编码不同,但编码的最大长度是 n。