关于树的遍历和题目
目录
关于树的遍历和题目
用链式前向星实现孩子表示法
const int N = 1e5 + 10;
int id, e[2*N], ne[2*N], h[N];//哨兵位h存的是节点,ne和e两个数组存储的
//是父与子的关系,每条边都要存两遍,所以数组的大小要开两倍!!!
void add(int a, int b)
{
id++;
e[id] = a;
ne[id] = h[a];
h[a] = id;
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
}
深度优先遍历–DFS
法一:用vector实现
const int N = 1e5 + 10;
vector<int> edges[N];
bool st[N];
void dfs(int u)
{
cout << u << " ";
st[u] = true;
for (auto v : edges[u])
{
if (!st[v])
{
dfs(v);
}
}
}
int main()
{
int n;
cin >> n;
for (int i = 1; i < n; i++)
{
int a, b;
cin >> a >> b;
edges[a].push_back(b);
edges[b].push_back(a);
}
dfs(1);
}
法二:用链式前向星
const int N = 1e5 + 10;
int h[N], e[2 * N], ne[2 * N],id;
bool st[N];
void add(int a, int b)
{
id++;
e[id] = b;
ne[id] = h[a];
h[a] = id;
}
void dfs(int u)
{
cout << u << " ";
st[u] = true;
for (int i = h[u]; i; i = ne[i])
{
int v = e[i];
if (!st[v])
dfs(v);
}
}
int main()
{
int n;
cin >> n;
for (int i = 1; i < n; i++)
{
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
dfs(1);
}
宽度优先遍历–BFS
法一:
#include <vector>
#include <queue>
using namespace std;
const int N = 1e5 + 10;
vector<int> edges[N];
bool st[N];
void bfs(int u)
{
queue<int> q;
q.push(1);
st[1] = true;
while (q.size())
{
auto u = q.front();
q.pop();
cout << u << " ";
for (auto v : edges[u])
{
if (!st[v])
{
st[v] = true;
q.push(v);
}
}
}
}
int main()
{
int n;
cin >> n;
for (int i = 1; i < n; i++)
{
int a, b;
cin >> a >> b;
edges[a].push_back(b);
edges[b].push_back(a);
}
bfs(1);
return 0;
}
法二:
const int N = 1e5 + 10;
int h[N], e[2 * N], ne[2 * N], id;
bool st[N];
void bfs(int u)
{
queue<int> q;
q.push(u);
st[u] = true;
cout << u << " ";
for (int i = h[u]; i; i = ne[i])
{
int v = e[i];
if (!st[v])
{
q.push(v);
st[v] = true;
}
}
}
void add(int a, int b)
{
id++;
e[id] = b;
ne[id]=h[a];
h[a] = id;
}
int main()
{
int n;
cin >> n;
for (int i = 1; i < n; i++)
{
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
bfs(1);
return 0;
}
二叉树问题
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N = 110;
int n;
vector<int> edges[N];
int fa[N], dist[N];
int dfs(int u)
{
int ret = 0;
for (auto v : edges[u])
{
ret = max(ret, dfs(v));
}
return ret + 1;
}
int bfs()
{
queue<int> q;
q.push(1);
int ret = 0;
while (q.size())
{
int sz = q.size();
ret = max(ret, sz);
while (sz--)
{
int u = q.front();
q.pop();
for (auto v : edges[u])
{
q.push(v);
}
}
}
return ret;
}
int main()
{
cin >> n;
for (int i = 1; i < n; i++)
{
int u, v;
cin >> u >> v;
edges[u].push_back(v);
fa[v] = u;
}
cout << dfs(1) << endl;
cout << bfs() << endl;
int x, y;
while (x != 1)
{
dist[fa[x]] = dist[x] + 1;
x = fa[x];
}
int len = 0;
while (y != 1 && dist[y] == 0)
{
len++;
y = fa[y];
}
cout << dist[y] * 2 + len << endl;
return 0;
}
已知前序,中序遍历求后序遍历
string a,b;
void dfs2(int l1, int r1, int l2, int r2)
{
if (l1 > r1) return;
int p = l1;
while (a[p]!= b[l2])
p++;
dfs2(l1, p - 1, l2 + 1, l2 + p - l1);
dfs2(p + 1, r1, l2 + p - l1 + 1, r2);
cout << b[l2];
}
int main()
{
cin >> a >> b;
dfs2(0, a.size() - 1, 0, b.size());
return 0;
}