二叉树从入门到AC(1)构建和前中后序遍历

名词解释与性质

首先援引百度百科:
在这里插入图片描述
这里补充一张图了解马上用到的例子:
在这里插入图片描述

一、如何构建一颗二叉树

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

typedef struct BTNode
{
    
    
    int data;
    struct BTNode *Left;
    struct BTNode *Right;
}Node;


//创建二叉树,按前序输入
Node* createBTree()
{
    
    
    Node *p;
    int ch;
	//printf("输入data");
    scanf("%d",&ch);
    if(ch == 0)     //如果到了叶子节点,接下来的左、右子树分别赋值为0
    {
    
    
        p = NULL;
    }
    else
    {
    
    
        p = (Node*)malloc(sizeof(Node));
        p->data = ch;
        p->Left  = createBTree();  //递归创建左子树
        p->Right = createBTree();  //递归创建右子树
    }
    return p;
}
int main()
{
    
    
	int i;
    Node *root = NULL;
    root = createBTree();
 return 0;
 }

这是一个按前序输入用双指针链表构建的二叉树,我们可以发现,链表仅仅只是一种储存的方式,对二叉树遍历的顺序(也是输入的顺序)才是真正的重点。
以前序:1245367为例
输入时为 1 2 4(叶子结点)0 0 5(叶子结点) 0 0 3 6(叶子结点)00 7(叶子结点) 00

二、二叉树的前中后序遍历

遍历的序

遍历即按一定顺序遍历二叉树的每一个结点
顺序有如下三种:

(1)前(先)序遍历(根左右)

(2)中序遍历(左根右)

(3)后序遍历(左右根)

于是在面对一颗二叉树时,我们可以根据如上法则递归写出前中后序遍历。
举个栗子:在这里插入图片描述

前序:ABDECFG
既然是根左右递归,先写根A及其左子结点右子结点
A B C;
在这里插入图片描述

然后开始递归,当B为根时,在B后加上左右子结点D,E
A B DE C;
在这里插入图片描述

当C为根时在C后加上左右子结点 F G
A B DE C FG;
因为DFEG后再无子结点递归结束如上为遍历结果。
在这里插入图片描述

中序方法如上:先写B A C;
按照左根右为B补充:
DBE A C;
为C补充得最终解:
DBEAFCG;

后序如上同理:
B C A ;
D E B C A;
D E B F G C A;
得解。
任意二叉树都可通过如上递归写出前中后序,而这种递归方法也将不断运用在之后的算法中。

进阶与例题

如何用代码求解出一个二叉树的序呢,
我们可以通过前序和中序来确认一棵二叉树,并顺之求出后序;
也可以通过中序和后序来确认,求其前序
仅仅是前序和后序是无法构建一棵二叉树的;
用个例题来说明:
Input:
两行分别输入前序和中序
Output:
输出后序

思路:我们并不需要急于去构建一棵二叉树,在拥有前序和中序的情况下,树本身已经按照上述的规则建立好了,虽然是仅仅存在于数组中。换言之,二叉树作为一种数据结构,其真正的内涵在于其顺序,而不是没有灵魂的使用指针链表来储存。
那么前序是根左右,中序是左根右,我们先通过前序的找到根(前序的第一个),此根在中序中的左边为左子树右边为右子树,然后进行上述的递归,并输出该结点。
通俗地解释一下理解误区:进行递归再输出,那么第一个输出的是DFS最深的结果,最后输出的才是当前结果。
以前序 A B C为例,中序为 B A C,为求后序,先找到根A,在中序中A的左边B右边C,递归到B,无子树输出,递归到C无子树输出,递归完成输出A。
代码:

#include<stdio.h>
#include<string.h>
char a[28],b[28];
void dfs(int w,int x,int y,int z)//深搜
{
    
    int i=0,j=0;
    if(w>x||y>z)//无法继续递归时
return;
for(i=w;i<=x;i++)
    if(a[i]==b[y])//在中序中找到根
{
    
    dfs(w,i-1,y+1,y+i-w);//递归左子树
dfs(i+1,x,y+i-w+1,z);//递归右子树
        printf("%c",a[i]);//递归完后输出,注意,是递归完
}
}
int main()
{
    
    
int i=0,j=0,k=0;
scanf("%s",b);//输入前序
scanf("%s",a);//输入中序
j=strlen(a);
k=strlen(b);
dfs(0,j-1,0,k-1);//进入递归
    return 0;
}

关于dfs与二叉树,在DFS与排列组合
中有提及,但在那时的二叉树更像一种逻辑判断结构而不是存储结构。
有时间再更新。

猜你喜欢

转载自blog.csdn.net/weixin_43736127/article/details/113797972
今日推荐