扩展先序遍历序列创建二叉链表与三种遍历

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

#define DataType char
#define MAXSIZE 1000
int count = 0;  //统计节点数

typedef struct Node
{
    DataType data;
    struct Node * Lchild;
    struct Node * Rchild;
    // struct Node * Parent;
} BiTNode,* BiTree;
 
 void CreateBiTree(BiTree * root)
 {
     char ch;
     ch = getchar();
     if(ch == ' ')          //空格代表为空
        * root = NULL;
     else
     {
        *root = (BiTree)malloc(sizeof(BiTNode));
        (*root)->data = ch;
        CreateBiTree(&((*root)->Lchild));
        CreateBiTree(&((*root)->Rchild));
     }
 }
 
 void PreOrder(BiTree root) //先序
 {
     if(root)
     {
         putchar(root->data);
         PreOrder(root->Lchild);
         PreOrder(root->Rchild);
     }
 }
 void InOrder(BiTree root)  //中序
 {
     if(root)
     {
         InOrder(root->Lchild);
         putchar(root->data);
         InOrder(root->Rchild);
     }
 }
 void PostOrder(BiTree root)    //后序
 {
     if(root)
     {
         PostOrder(root->Lchild);
         PostOrder(root->Rchild);
         putchar(root->data);
         count++;       //后序遍历同时计节点数
     }
 }
int leaf(BiTree root)  //输出叶子节点和统计叶子节点个数
{
    if(root == NULL) return 0;
    if(!root->Lchild && !root->Rchild) 
    {
        putchar(root->data);
        return 1;    //当前节点无孩子,为叶子节点
    }
    return leaf(root->Lchild) + leaf(root->Rchild);
}
int TreeDepth(BiTree root)  //求树高度
{
    int h,lh,rh;
    if(root == NULL) return 0;
    lh = TreeDepth(root->Rchild);
    rh = TreeDepth(root->Lchild);
    h = (lh>rh ? lh : rh) + 1;
    return h;
}
void PrintfTree(BiTree root, int h) //按树状打印二叉树,先右后左中序遍历树
{                                   //结点的横向位置有结点在树中的层次决定,h表示结点的层次,控制结点输出左右位置
    if(root == NULL) return;
    PrintfTree(root->Rchild,h+4);   //每个层次相隔4个空格
    for (int i = 0; i < h; i++) 
        printf(" ");
    printf("%c\n",root->data);
    PrintfTree(root->Lchild,h+4);
}

int main(int argc, char **argv) {

    int LeafNum,Depth;
    BiTree Tree;

    printf("按先序输入建立树:");
    CreateBiTree(&Tree);
    
    printf("先序:");
    PreOrder(Tree);
    
    printf("\n中序:");
    InOrder(Tree);
    
    printf("\n后序:");
    PostOrder(Tree);
    
    printf("\n叶子节点:");
    LeafNum = leaf(Tree);
    printf("\n节点数:%d",count);
    printf("    叶子节点数为%d",LeafNum);
    
    Depth = TreeDepth(Tree);
    printf("\n树高度为:%d\n",Depth);
    
    PrintfTree(Tree,1);
    
    return 0;
}

好的,以下是C语言代码实现: ```c #include <stdio.h> #include <stdlib.h> typedef struct TreeNode { char data; struct TreeNode *left; struct TreeNode *right; } TreeNode; TreeNode *buildTree(char *preorder, char *inorder, int len) { if (len == 0) { return NULL; } TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode)); root->data = *preorder; int rootIndex = 0; for (int i = 0; i < len; i++) { if (*(inorder + i) == *preorder) { rootIndex = i; break; } } root->left = buildTree(preorder + 1, inorder, rootIndex); root->right = buildTree(preorder + rootIndex + 1, inorder + rootIndex + 1, len - rootIndex - 1); return root; } void postorderTraversal(TreeNode *root) { if (root == NULL) { return; } postorderTraversal(root->left); postorderTraversal(root->right); printf("%c ", root->data); } int main() { char preorder[20], inorder[20]; printf("请输入二叉树先序遍历序列:"); scanf("%s", preorder); printf("请输入二叉树的中序遍历序列:"); scanf("%s", inorder); int len = strlen(preorder); TreeNode *root = buildTree(preorder, inorder, len); printf("二叉树的后序遍历序列为:"); postorderTraversal(root); printf("\n"); return 0; } ``` 解释一下代码: 首先定义一个二叉树节点的结构体 `TreeNode`,包括节点的数据 `data`、指向左子树的指针 `left` 和指向右子树的指针 `right`。 然后定义一个递归函数 `buildTree`,用于根据先序遍历序列和中序遍历序列构建二叉树。函数接受三个参数,分别是先序遍历序列、中序遍历序列序列长度。如果序列长度为0,直接返回NULL。否则,取出先序遍历序列中的第一个元素作为根节点,然后在中序遍历序列中找到根节点的位置,将序列分为左子树和右子树两部分,递归调用 `buildTree` 函数构建左右子树,最后返回根节点。 接着定义一个递归函数 `postorderTraversal`,用于后序遍历二叉树并输出节点数据。函数接受一个参数,即二叉树的根节点。如果根节点为空,直接返回。否则,先递归遍历左子树,再递归遍历右子树,最后输出根节点的数据。 最后在 `main` 函数中,读入先序遍历序列和中序遍历序列,调用 `buildTree` 函数构建二叉树,然后调用 `postorderTraversal` 函数输出后序遍历序列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值