P1030 [NOIP2001 普及组] 求先序排列 & P1827 [USACO3.4] 美国血统 American Heritage
这次分享一下这两道关于树的基础题的思路(套路)。
(我终于弄懂这种题目and独立编写ac代码啦!!!走出舒适圈的感觉真爽!!!)
这两道题考察的通过两种遍历方式推导出第三种遍历方式,实质上考察的都是对于树这种数据结构的遍历的理解以及运用。
想了解关于树的遍历的相关知识点可以移步其他巨犇的文章,这里不多赘述。
前序遍历:中左右
中序遍历:左中右
后序遍历:左右中
(这里的左指的是左孩子节点,中指的是父亲节点,右指的是右孩子节点)
注意点:
在后序遍历中,最后一个节点一定是根节点(对于每一颗子树也成立)
在前序遍历中,第一个节点一定是根节点(对于每一颗子树也成立)
我的思路(套路)就是:
首先,根据前序遍历确定根节点,并通过根节点划分出左右子树。
然后,定位两颗子数对应的前序和中序遍历串,递归的进行上述操作。
(可能有点难理解,看看代码吧,拿出笔和草稿纸亲自动手推一下,应该就能理解啦)
P1030 [NOIP2001 普及组] 求先序排列 AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
char hou[10];
char zhong[10];
int find(char r_hou)
{
for(int i=0;i<strlen(hou);i++)
{
if(r_hou==zhong[i])
{
return i;
}
}
}
void dfs(int zhong_l,int zhong_r,int hou_l,int hou_r)
{
int head=find(hou[hou_r]);
printf("%c",hou[hou_r]);
if(head>zhong_l) dfs(zhong_l,head-1,hou_l,hou_r-zhong_r+head-1);
if(head<zhong_r) dfs(head+1,zhong_r,hou_l+head-zhong_l,hou_r-1);
}
int main()
{
memset(hou,0,sizeof(hou));
memset(zhong,0,sizeof(zhong));
scanf("%s",zhong);
scanf("%s",hou);
dfs(0,strlen(zhong)-1,0,strlen(hou)-1);
return 0;
}
P1827 [USACO3.4] 美国血统 American Heritage
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
char qian[100];
char zhong[100];
char ans[100];
int index=0;
int find(char a)
{
for(int i=0;i<(int )strlen(zhong);i++)
{
if(a==zhong[i]) return i;
}
}
void dfs(int qian_l,int qian_r,int zhong_l,int zhong_r)
{
int m=find(qian[qian_l]);
if(m>zhong_l) dfs(qian_l+1,qian_r-zhong_r+m+1,zhong_l,m-1);
if(m<zhong_r) dfs(qian_l+m-zhong_l+1,qian_r,m+1,zhong_r);
printf("%c",qian[qian_l]);
}
int main()
{
memset(qian,0,sizeof(qian));
memset(zhong,0,sizeof(zhong));
scanf("%s",zhong);
scanf("%s",qian);
dfs(0,strlen(qian)-1,0,strlen(zhong)-1);
return 0;
}
补一道同类型题目,已知中序遍历和后序遍历要求构造二叉树。
leetcode 104:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int leninorder;
int find(int *inorder,int target)
{
for(int i=0;i<leninorder;i++)
{
if(inorder[i]==target)
{
return i;
}
}
return 0;
}
struct TreeNode *dfs(int *inorder,int ileft,int iright,int *postorder,int pleft,int pright)
{
if(ileft==iright)
{
struct TreeNode *p;
p=(struct TreeNode*)malloc(sizeof(struct TreeNode));
p->val=inorder[ileft];
p->right=p->left=NULL;
return p;
}
int mid=find(inorder,postorder[pright]);
int lenl=mid-ileft;
int lenr=iright-mid;
struct TreeNode *root;
root=(struct TreeNode*)malloc(sizeof(struct TreeNode));
root->val=inorder[mid];
if(lenl!=0) root->left=dfs(inorder,ileft,mid-1,postorder,pleft,pright-lenr-1);
else root->left=NULL;
if(lenr!=0) root->right=dfs(inorder,mid+1,iright,postorder,pleft+lenl+1,pright-1);
else root->right=NULL;
return root;
}
struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize)
{
leninorder=inorderSize;
struct TreeNode *root;
root=dfs(inorder,0,inorderSize-1,postorder,0,postorderSize-1);
return root;
}
感谢!
世界会向那些有目标和远见的人让路!让我们一起加油!