前言
因为这个代码十分抽象和牛逼,因此我们先从代码入手
代码
#include <bits/stdc++.h>
using namespace std;
typedef struct Node
{
char data;
struct Node *l;
struct Node *r;
} N, *Tr;
string mid, pre;
Tr build(int x, int y, int p, int q)
{
int i;
if (x > y || p > q)
return NULL;
Tr root = new N;
root->data = pre[x];
root->l = root->r = NULL;
for (i = p; i <= q; i++)
if (pre[x] == mid[i])
break;
root->l = build(x + 1, x + i - p, p, i - 1);
root->r = build(x + i - p + 1, y, i + 1, q);
return root;
}
void prt(Tr root)
{
cout << root->data << " ";
if (root->l)
prt(root->l);
if (root->r)
prt(root->r);
}
int main()
{
cin >> pre >> mid;
int len = mid.size();
N *root;
root = build(0, len - 1, 0, len - 1);
prt(root);
return 0;
}
思路
这个代码最抽象的点是build那一处,思路是分治
root->l = build(x + 1, x + i - p, p, i - 1);
root->r = build(x + i - p + 1, y, i + 1, q);
可以这么理解,build一共四个参数x y p q
x y 是指先序遍历的首末,而p q是指中序遍历的首末,通过i,我们找到了pre[x]和mid[i] 相等的点,然后i-p是所在该节点左边的元素,因此左子树就是按照i+1到x+p-i的先序遍历,按照p到i-1中序遍历 右子树就是按照x+i-p+1到y的先序遍历,按照i+1,q的中序遍历,简而言之 ,这就是一个分治问题