二叉树递归遍历及其相关操作

二叉树的基本结构是由根节点、左子树、右子树三个部分构成。其有3中遍历方式:
1. 先序遍历:根节点、左子树、右子树
2. 中序遍历:左子树、根节点、右子树
3. 后序遍历:左子树、右子树、根节点
输入的二叉树AB#DG###CE##FH###,3种遍历节点序列如下:
1.先序遍历: ABDGCEFH
2.中序遍历: BGDAECHF
3.后序遍历: GDBEHFCA
下面是其相关操作的实现代码:


#include<stdio.h>
#include<stdlib.h>

/**性质:
*1.在二叉树的第i层上至多有2^(i-1)个节点(i>=1)
*2.深度为k的二叉树至多有2^k-1个节点(k>=1)
*3.对于任意一棵二叉树T,若终端节点数为n0,度为2的节点数为n2,则n0=n2+1
*4.具有n个节点的完全二叉树的深度为log2n+1
*/
static int count=0,depth=0,h=1;
typedef char DataType;
typedef struct Node
{
    DataType data;
    struct Node *lchild;
    struct Node *rchild;
} BiTNode,*BiTree;
//初始化二叉树
void InitBiTree(BiTree *root);
void InitBiTree(BiTree *root)
{
    *root=NULL;
}
//二叉树判空
int EmptyBitTree(BiTree root);
int EmptyBitTree(BiTree root)
{
    if(root)    return 1;
    else    return 0;
}
//创建二叉树
void CreateBiTree(BiTree *root);
void CreateBiTree(BiTree *root)
{
    DataType ch;
    ch=getchar();
    if(ch=='#')     //空内容
        *root=NULL;
    else
    {
        *root=(BiTree)malloc(sizeof(BiTNode));
        (*root)->data=ch;
        CreateBiTree(&((*root)->lchild));   //创建左子树
        CreateBiTree(&((*root)->rchild));   //创建右子树
    }
}
//销毁二叉树
void DestroyBiTree(BiTree *root);
void DestroyBiTree(BiTree *root)
{
    if(*root)
    {
        if((*root)->lchild)
            DestroyBiTree(&((*root)->lchild));
        else
            DestroyBiTree(&((*root)->rchild));
        free(*root);
        *root=NULL;
    }
}
//输出节点值
void Visit(DataType ch);
void Visit(DataType ch)
{
    printf("%c",ch);
}
//按树状打印二叉树
void PrintTree(BiTree root,int h);
void PrintTree(BiTree root,int h)
{
    int i;
    if(root=NULL)   return;
    PrintTree(root->rchild,h+1);
    for(i=0; i<h; i++)  //层次决定节点的左右位置
        printf(" ");
    printf("%c\n",root->data);
    PrintTree(root->lchild,h+1);
}
//先序遍历二叉树
void PreOrder(BiTree root);
void PreOrder(BiTree root)
{
    if(root)
    {
        Visit(root->data);
        PreOrder(root->lchild);
        PreOrder(root->rchild);
    }
}
//中序遍历二叉树
void InOrder(BiTree root);
void InOrder(BiTree root)
{
    if(root)
    {
        InOrder(root->lchild);
        Visit(root->data);
        InOrder(root->rchild);
    }
}
//后序遍历二叉树
void PostOrder(BiTree root);
void PostOrder(BiTree root)
{
    if(root)
    {
        PostOrder(root->lchild);
        PostOrder(root->rchild);
        Visit(root->data);
    }
}
//先序遍历统计二叉树的节点数
int PreOrderNode(BiTree root);
int PreOrderNode(BiTree root)
{
    if(root)
    {
        count++;
        PreOrderNode(root->lchild);
        PreOrderNode(root->rchild);
    }
}
//中序遍历输出二叉树的叶子结点
void InOrderLeafNode(BiTree root);
void InOrderLeafNode(BiTree root)
{
    if(root)
    {
        InOrderLeafNode(root->lchild);
        if(root->lchild==NULL&&root->rchild==NULL)
            printf("%c ",root->data);
        InOrderLeafNode(root->rchild);
    }
}
//后序遍历统计叶子结点数目
int GetLeafNode(BiTree root);
int GetLeafNode(BiTree root)
{
    int nl,nr;
    if(root==NULL)  return 0;
    if((root->lchild==NULL)&&(root->rchild==NULL))    return 1;
    nl=GetLeafNode(root->lchild);
    nr=GetLeafNode(root->rchild);
    return (nl+nr);
}
//1.全局变量法求二叉树高度
void TreeDepth(BiTree root,int h);
void TreeDepth(BiTree root,int h)
{

    if(h>depth)
        depth=h;    //当前节点数大于depth,z则更新
    TreeDepth(root->lchild,h+1);
    TreeDepth(root->rchild,h+1);
}
//2.通过函数值返回求二叉树高度
int PostTreeDepth(BiTree root);
int PostTreeDepth(BiTree root)
{
    int hl,hr,height;
    if(root==NULL)  return 0;
    else
    {
        hl=PostTreeDepth(root->lchild);
        hr=PostTreeDepth(root->rchild);
        height=(hl>hr?hl:hr)+1;
        return height;
    }
}
//求节点双亲
BiTree Parent(BiTree root,BiTree current);
BiTree Parent(BiTree root,BiTree current)
{
    BiTree p;
    if(root==NULL) return NULL;
    if(root->lchild==current||root->rchild==current)
        return root;
    p=Parent(root->lchild,current);
    if(p!=NULL)
        return p;
    else
        return Parent(root->rchild,current);
}
//二叉树相似性判定
int like(BiTree t1,BiTree t2);
int like(BiTree t1,BiTree t2)
{
    int like1,like2;
    if(t1==NULL&&t2==NULL)
        return 1;   //t1,t2均空,则相似
    else if(t1==NULL||t2==NULL)
        return 0;   //t1,t2仅一棵空,不相似
    else
    {
        like1=like(t1->lchild,t2->rchild);
        like2=like(t1->lchild,t2->rchild);
        return like1&&like2;
    }
}
//得到根节点
DataType GetRoot(BiTree root);
DataType GetRoot(BiTree root)
{
    if(EmptyBitTree(root))
        return root->data;
    else
        return '#';
}
//旋转左右子树
void Swap(BiTree *root);
void Swap(BiTree *root)
{
    BiTree temp;
    if(*root)
    {
        temp=(*root)->lchild;
        (*root)->lchild=(*root)->rchild;
        (*root)->rchild=temp;
        Swap(&((*root)->lchild));
        Swap(&((*root)->rchild));
    }
    else
        return ;
}

/*请输入二叉树的节点内容:    AB#DG###CE##FH###

先序遍历:   ABDGCEFH
中序遍历:   BGDAECHF
后序遍历:   GDBEHFCA*/
int main()
{
    BiTree root;
    InitBiTree(&root);
    printf("请输入二叉树的节点内容:    ");
    CreateBiTree(&root);
    printf("构造二叉树后是否为空?%d(0:空 1:非空)\n",EmptyBitTree(root));
    //TreeDepth(root,h);
    //printf("树的深度为%d\n",depth);
    printf("树的深度为%d\n",PostTreeDepth(root));
    printf("根节点是:%c",GetRoot(root));
    PreOrderNode(root);
    printf("\n先序统计输出二叉树节点数:%d",count);
    printf("\n后序遍历统计叶子节点数目:%d",GetLeafNode(root));
    printf("\n中序输出二叉树叶子结点:");
    InOrderLeafNode(root);
    printf("\n双亲为:%c",Parent(root,root->rchild->lchild)->data);     //E的双亲
    printf("\n先序遍历:   ");
    PreOrder(root);
    printf("\n中序遍历:   ");
    InOrder(root);
    printf("\n后序遍历:   ");
    PostOrder(root);

    printf("\n交换左右子树后:");
    Swap(&root);
    printf("\n先序遍历:   ");
    PreOrder(root);
    printf("\n中序遍历:   ");
    InOrder(root);
    printf("\n后序遍历:   ");
    PostOrder(root);
    DestroyBiTree(&(root->rchild));
    printf("\n删除右子树后:\n");
    printf("\n先序遍历:   ");
    PreOrder(root);
    printf("\n中序遍历:   ");
    InOrder(root);
    printf("\n后序遍历:   ");
    PostOrder(root);
    printf("\n销毁二叉树:\n");
    DestroyBiTree(&root);
    printf("构造二叉树后是否为空?%d(0:空 1:非空)\n",EmptyBitTree(root));
    printf("树的深度为%d\n",PostTreeDepth(root));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值