c语言二叉树的创建与遍历_二叉树-镜像二叉树(C++)

a3da0ad47fac9f2d7226fe950de53cf2.png

叨叨Chen的第一篇知乎文章,就从最近探索的二叉树开始吧~

既然读者点击进来,那么叨叨Chen就假设读者是有一定二叉树基础的,因此关于二叉树的基础概念不再详细叙述。

Punchline-------------------------------------------------------------------

Task:根据用户输入二叉树的先序遍历和中序遍历的字符串创建二叉树,输出原始二叉树的后序遍历和镜像二叉树的后序遍历。

Input:用户输入两行字符串,第一行是pre_str代表先序遍历结果,第二行in_str代表中序遍 历结果,假设两行字符串都是相同长度;

Output:输出两行,第一行是原始二叉树的后序遍历,第二行是镜像二叉树的后序遍历。

Realize:

  1. 创建二叉树(build):读取pre_str可以得到根结点,并在in_str中定位,返回根结点位置pos,进而以相同思路分别遍历在pos的左边和右边;(递归实现)会涉及初始化结点的函数;
  2. 后序遍历(postorder):左右根(LRD);
  3. 逆后序遍历(inverpostorder):读者通过作图不难发现镜像二叉树的实现就是在输出上作相应改变,其输出结点顺序为右左根(RLD)。

------------------------------------------------------------------------------

Let's get it!

//首先是头文件;这里加载了三个库,主要为了int main函数里的一些命令的实现。在后面会详细叙述。

#include

//定义二叉树结点;

typedef struct Node
{
    char data;
    Node *lc,*rc;
};

note:使用typedef是为了兼容C语言。实际中,我们还可以见到下列的结构体形式,

typedef struct Node
{
    char data;
    Node *lc,*rc;
}*BiTree;

这样做的目的也是便于后面声明指针型的结点,这里叨叨Chen还是使用的第一种,叨叨Chen后续的文章会用到第二种。

//功能;下面是实现整个过程涉及到的一些函数

//初始化结点
Node *init(char e)
{
    Node *node=(Node*)malloc(sizeof(Node));
    node->data=e;
    node->lc=NULL;node->rc=NULL;
    return node;
}
//创建二叉树
Node *build(char pre_str[],char in_str[],int len)
{
    Node *p=init(pre_str[0]);
    int pos=strchr(in_str,pre_str[0])-in_str;//strchr是库string中的函数
    if(pos>0){p->lc=build(pre_str+1,in_str,pos);}
    if(len-pos-1>0){p->rc=build(pre_str+pos+1,in_str+pos+1,len-pos-1);}
    return p;
}
//后序遍历输出二叉树
void postorder(Node *node)
{
    if(node->lc){postorder(node->lc);}
    if(node->rc){postorder(node->rc);}
    cout<<node->data;
}
//逆后序遍历输出二叉树
void inverpostorder(Node *node)
{
    if(node->rc){inverpostorder(node->rc);}
    if(node->lc){inverpostorder(node->lc);}
    cout<<node->data;
}

//主函数

int main()
{
    string pre_str;
    string in_str;
    cin>>pre_str;
    cin>>in_str;
    int len=pre_str.length();
    char *pre_str1=(char*)pre_str.c_str();
    char *in_str1=(char*)in_str.c_str();
    Node *root=build(pre_str1,in_str1,len);
    postorder(root);printf("n");
    inverpostorder(root);printf("n");
    system("pause");
    return 0;
}

当然,看到这样的main函数头大了吧,这里主要是展示C++中关于字符串的一些命令的使用。可以与下面的main函数作对比。

int main()
{
    char pre_str[50], in_str[50];
    cin.getline(pre_str, 50);
    cin.getline(in_str, 50);
    int len = strlen(pre_str);
    Node* root = build(pre_str, in_str, len);
    postorder(root); printf("n");
    inverpostorder(root); printf("n");
    system("pause");
    return 0;
}

note:这里涉及字符串的一些功能[eg:.c_str()/cin.getline()],有些读者会觉得没必要,但站在用户的角度来上看,若用户只输入了一个空格呢,这时候cin还能读入并成功进入下一步的判断么?有兴趣的读者还可以了解下cin.get()/gets()/getchar()这三个命令的功能。

欢迎读者提出批评和建议,叨叨Chen会将好的建议追加在后面进行补充。

2020.10.08------------------------------------------------------------------It still comes---


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值