树(C)

本文详细介绍了二叉树的基本概念及各种遍历方法,包括先序、中序和后序遍历,并提供了具体的源代码实现。此外,还探讨了如何根据先序和中序遍历结果重建二叉树,讲解了二叉排序树和哈夫曼树的构建过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

4

 

 

4.1 二叉树的遍历

 

4.1.1 先序遍历

 

[算法描述]

1.若二叉树为空则退出

  否则:

  (1)访问处理根节点;

  (2)先序遍历左子树;

  (3)先序遍历右子树.

[源程序]

数组:

void PreOrder(struct TreeType *Tree, int x)

{

    if(x!=0)

    {

       printf("%d",Tree[x].Data);

       PreOrder(Tree,Tree[x].Lch);

       PreOrder(Tree,Tree[x].Rch);

    }

}

链表:

struct TreeType

{

    intDate;

    structTreeType *Lch;

    structTreeType *Rch;

};

 

void PreOrder(struct TreeType *Tree)

{

    if(Tree!=NULL)

    {

       printf("%d",(*Tree).Data);

       PreOrder((*Tree).Lch);

       PreOrder((*Tree).Rch);

    }

}

 

4.1.2 中序遍历

 

[算法描述]

1.若二叉树为空则退出

  否则:

  (1)中序遍历左子树;

  (2)访问处理根节点;

  (3)中序遍历右子树.

[源程序]

数组:

void InOrder(struct TreeType *Tree, int x)

{

    if(x!=0)

    {

       InOrder(Tree,Tree[x].Lch);

       printf("%d",Tree[x].Data);

       InOrder(Tree,Tree[x].Rch);

    }

}

链表:

struct TreeType

{

    intDate;

    structTreeType *Lch;

    structTreeType *Rch;

};

 

void InOrder(struct TreeType *Tree)

{

    if(Tree!=NULL)

    {

       InOrder((*Tree).Lch);

       printf("%d",(*Tree).Data);

InOrder((*Tree).Rch);

    }

}

 

4.1.3 后序遍历

 

[算法描述]

1.若二叉树为空则退出

  否则:

  (1)后序遍历左子树;

  (2)后序遍历右子树;

  (3)访问处理根节点.

[源程序]

数组:

void PostOrder(struct TreeType *Tree, int x)

{

    if(x!=0)

    {

       PostOrder(Tree,Tree[x].Lch);

       PostOrder(Tree,Tree[x].Rch);

       printf("%d",Tree[x].Data);

    }

}

链表:

struct TreeType

{

    intDate;

    structTreeType *Lch;

    structTreeType *Rch;

};

 

void PostOrder(struct TreeType *Tree)

{

    if(Tree!=NULL)

    {

       PostOrder((*Tree).Lch);

       PostOrder((*Tree).Rch);

       printf("%d",(*Tree).Data);

    }

}

 

4.2 根据先序和中序遍历建立二叉树

 

[算法描述]

1.在中序遍历中找出先序的第一个元素(即根);

2.根据根在中序遍历中划分出左右子树;

3.对左右子树执行以上操作.

[源程序]

struct TreeType

{

    intLch,Rch;

} ;

 

int Pos(int c, int *s); //求元素c在数组s中的位置

void Copy(int *Input, int Pos, int x, int*Output); //在数组Input中从Pos位置开始顺序截取长度为x的数组,保存在Output中

int Length(int *s); //测量数组s的长度(元素个数)

 

void Create(struct TreeType *Tree, int *PreOrder, int*InOrder)

{

    intx,LTP[256],RTP[256],LTI[256],RTI[256]; //均初始化为0

 

   x=Pos(PreOrder[1],InOrder);

   Copy(InOrder,1,x-1,LTI);

   Copy(InOrder,x+1,Length(InOrder)-x,RTI);

   Copy(PreOrder,2,Length(LTI),LTP);

   Copy(PreOrder,Length(LTI)+2,Length(RTI),RTP);

    if(Length(LTP)>0)

    {

       Tree[PreOrder[1]].Lch=LTP[1];

       Create(Tree,LTP,LTI);

    }

    if(Length(RTP)>0)

    {

       Tree[PreOrder[1]].Rch=RTP[1];

       Create(Tree,RTP,RTI);

    }

}

 

4.3 二叉排序树

 

[算法描述]

如果树为空,则将元素添加至根节点;如果树不为空则与根节点比较,如果小于等于根节点的值,则向左子树添加,否则就向右子树添加.

[源程序]

struct TreeType

{

    intData,Lch,Rch;

} ;

 

void Insert(struct TreeType *Tree, int x, int Root, int*Count)

{

    if(*Count==0) Tree[++(*Count)].Data=x;

    else

       if (x<=Tree[Root].Data)

       {

           if (Tree[Root].Lch==0)

           {

               (*Count)++;

               Tree[Root].Lch=*Count;

               Tree[*Count].Data=x;

           }

           else Insert(Tree,x,Tree[Root].Lch,Count);

       }

       else

           if (Tree[Root].Rch==0)

           {

               (*Count)++;

               Tree[Root].Rch=*Count;

               Tree[*Count].Data=x;

           }

           else Insert(Tree,x,Tree[Root].Rch,Count);

}

 

4.4 建立哈夫曼树

 

[算法描述]

1.将给定的n个结点构成n棵二叉树的集合F={T1,T2,T3,...,Tn}.其中每棵二叉树Ti中只有一个权值为wi的根结点ki,其左右子树均为空;

2.在F中选取根结点最小的两棵二叉数作为左右子树,构造一棵新的二叉树,并且置新的二叉树的根结点的权值为其左右子树根结点的权值之和;

3.在F中删除这两棵二叉树,同时将新得到的二叉数加入F中;

4.重复2,3,直到F中只含有一棵二叉树为止.

这棵二叉树就是哈夫曼树.

[源程序]

struct TreeType

{

    intData,Lch,Rch;

} ;

 

struct RecType

{

    intData,Addr;

} ;

 

void Huffman(struct TreeType *Tree, int *Root, struct RecType*w, int n)

{

    inti,Count;

 

    for(i=1;i<=n;i++)

    {

       Tree[i].Data=w[i].Data;

       Tree[i].Lch=0;

       Tree[i].Rch=0;

       w[i].Addr=i;

    }

   *Root=n;

   Count=n;

    while(Count>1)

    {

       Sort(w,Count); //对w的前count个元素按data域升序排序

       (*Root)++;

       Tree[*Root].Data=w[1].Data+w[2].Data;

       Tree[*Root].Lch=w[1].Addr;

       Tree[*Root].Rch=w[2].Addr;

       w[1].Data=Tree[*Root].Data;

       w[1].Addr=*Root;

       w[2]=w[Count--];

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值