1. 树的深度优先遍历
题目背景
树的深度优先遍历最简单的实现方式是 递归 实现。
从根节点出发依次遍历根节点的每颗子树,对于子树可以视作一颗新的树采用相同的策略继续往下遍历子树的子树,直到无子树为止。
题目描述
输入n个节点的树,节点从1至n编号,输出该树的深度优先遍历顺序。根节点编号为1。
输入格式
第一行输入正整数nn表示nn个节点的树,n∈[2,100000]n∈[2,100000]。
接下来n−1n−1行每行输入两个正整数a和b,表示节点b是节点a的子节点。
输出格式
输出树的深度优先遍历顺序,节点编号用空格隔开。
输入输出样例
输入 #1
7 2 5 1 2 1 3 1 4 4 6 4 7
输出 #1
1 2 5 3 4 6 7
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, a, b, vis[N];
vector<int> tr[N]; //vector存树
void dfs(int x) {
cout << x << " ";
vis[x] = 1; //标记该节点为已访问
for (auto y : tr[x]) //遍历tr的邻接点
if (!vis[y]) //如果该点未被访问说明为子节点 已访问为父节点
dfs(y);
}
int main() {
int n;
cin >> n;
for (int i = 1; i < n; i++) {
cin >> a >> b;
tr[a].push_back(b); //由于不知道节点之间的父子关系双向存边
tr[b].push_back(a);
}
dfs(1); //从根节点出发向下遍历
return 0;
}
2. 树的广度优先遍历
题目背景
树的广度优先遍历需要借助队列实现。
一、将根节点入队
二、循环队列直到队列为空
(1)取出队头存入临时变量hx
(2)队头元素出队
(3)输出队头hx
(4)遍历节点hx的所有孩子节点
子节点入队
题目描述
输入n个节点的树,节点从1至n编号,输出该树的广度优先遍历顺序。根节点编号为1。
输入格式
第一行输入正整数n表示n个节点的树,n∈[2,100000]n∈[2,100000]。
接下来n−1n−1行每行输入两个正整数a和b,表示节点b是节点a的子节点。
输出格式
输出树的广度优先遍历顺序,节点编号用空格隔开。
输入输出样例
输入 #1
7 2 5 1 2 1 3 1 4 4 6 4 7
输出 #1
1 2 3 4 5 6 7
#include <bits/stdc++.h>
using namespace std;
int n, a, b;
vector<int> tree[100005]; //vector存树
void bfs(int rx);
int main() {
cin >> n;
for (int i = 1; i < n; i++) {
cin >> a >> b;
tree[a].push_back(b);
}
bfs(1);
return 0;
}
void bfs(int rx) {
queue<int> q;
q.push(rx); //将根节点入队
while (q.size()) { //循环直到队列为空
int hx = q.front(); //取出队头
q.pop(); //元素出队
cout << hx << " ";
for (auto y : tree[hx]) //遍历hx的邻接点
q.push(y); //元素入队
}
}
3.二叉树的先序遍历
题目描述
输入一颗n个节点的二叉树,节点编号从1至n,输出该二叉树的先序遍历顺序。根节点编号为1。
输入格式
第一行输入正整数n表示n个节点的二叉树,n∈[2,1000]
接下来n行,第i行输入两个整数l和r,代表第i个节点的左右孩子节点的编号。若输入的数为 l = 0 表示该节点无左孩子,r = 0 表示该节点无右孩子。
输出格式
输出二叉树的先序遍历顺序,节点编号用空格隔开。
输入输出样例
输入 #1
4 2 3 4 0 0 0 0 0
输出 #1
1 2 4 3
#include<bits/stdc++.h>
using namespace std;
int l[1005],r[1005],n,x,y;
void dfs(int rt){
if(rt==0) return ; //该节点不存在
cout<<rt<<" "; //访问根节点(先序遍历 根左右)
dfs( l[rt] ); //访问左子树的根节点
dfs( r[rt] ); //访问右子树的根节点
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>l[i]>>r[i];
dfs(1);
return 0;
}
4. 二叉树的中序遍历
题目描述
输入一颗n个节点的二叉树,节点从1至n编号,输出该二叉树的中序遍历顺序。根节点编号为1。
输入格式
第一行输入正整数n表示n个节点的二叉树,n∈[2,1000]
接下来n行,第i行输入两个整数l和r,代表第i个节点的左右孩子节点的编号。若输入的数为 l = 0 表示该节点无左孩子,r = 0 表示该节点无右孩子。
输出格式
输出二叉树的中序遍历顺序,节点编号用空格隔开。
输入输出样例
输入 #1
4 2 3 4 0 0 0 0 0
输出 #1
4 2 1 3
#include<iostream>
using namespace std;
int n;
struct node{
int date;
int father;
int lchild, rchild;
};
node tree[1005];
void pero(int root){
if(root==0) return;
pero(tree[root].lchild);
cout << root << " ";
pero(tree[root].rchild);
}
int main(){
int n;
cin >> n;
for(int i=1; i<=n; i++){
cin >> tree[i].lchild >>tree[i].rchild;
}
pero(1);
return 0;
}
5. 二叉树的后序遍历
题目描述
输入一颗n个节点的二叉树,节点从1至n编号,输出该二叉树的后序遍历顺序。根节点编号为1。
输入格式
第一行输入正整数n表示n个节点的二叉树,n∈[2,1000]
接下来n行,第i行输入两个整数l和r,代表第i个节点的左右孩子节点的编号。若输入的数为 l = 0 表示该节点无左孩子,r = 0 表示该节点无右孩子。
输出格式
输出二叉树的序遍历顺序,节点编号用空格隔开。
输入输出样例
输入 #1
4 2 3 4 0 0 0 0 0
输出 #1
4 2 3 1
#include<iostream>
using namespace std;
int n;
struct node{
int date;
int father;
int lchild, rchild;
};
node tree[1005];
void pero(int root){
if(root==0) return;
pero(tree[root].lchild);
pero(tree[root].rchild);
cout << root << " ";
}
int main(){
int n;
cin >> n;
for(int i=1; i<=n; i++){
cin >> tree[i].lchild >>tree[i].rchild;
}
pero(1);
return 0;
}
6.二叉树的层次遍历
题目描述
输入一颗n个节点的二叉树,输出该二叉树的层次遍历顺序。根节点编号从1开始。
输入格式
第一行输入正整数n表示n个节点的二叉树,n∈[2,1000]
接下来n行,第i行输入两个整数l和r,代表第i个节点的左右孩子节点的编号。若输入的数为 l = 0 表示该节点无左孩子,r = 0 表示该节点无右孩子。
输出格式
输出二叉树的层次遍历顺序,节点编号用空格隔开。
输入输出样例
输入 #1
4 2 3 4 0 0 0 0 0
输出 #1
1 2 3 4
#include<bits/stdc++.h>
using namespace std;
struct Node {
int lc, rc;
} tr[1005];
int n;
void breOrder(int root) {
queue<int> q;
q.push(root);
while (q.size()) {
int hr = q.front();
q.pop();
cout << hr << " ";
if (tr[hr].lc) q.push(tr[hr].lc);
if (tr[hr].rc) q.push(tr[hr].rc);
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> tr[i].lc >> tr[i].rc;
breOrder(1);
return 0;
}
各位读者,这些题的确有些难(我做的时候差点逝了)
咳咳.....请细品
建议花大量时间食用