2020-PTA总决赛-L2-3 完全二叉树的层序遍历(深搜+一维数组模拟二叉树)
一维数组模拟二叉树:
leftNode = root * 2
rightNode = root * 2 + 1
leftNode表示左孩子在一维数组中的下标(一维数组下标从1开始)
rightNode表示右孩子在一维数组中的下标
root表示根节点下标
比如完全二叉树层序遍历为10 2 5 6 8 7 3
那么用一维数组模拟后tree = [null, 10, 2, 5, 6, 8, 7, 3]
下标的数学关系一目了然:
下标为1的是10,它的左孩子是1 * 2的位置上的2,右孩子是1 * 2 + 1的位置上的5
下标为2的是2,它的左孩子是2 * 2的位置上的6,右孩子是2 * 2 + 1位置上的8
深度优先搜索:
b站up“左程云”,他在经典递归里讲到了, java版本,c/c++/py用户可以听他的思路。
b站up“一只会code的小金鱼”,讲了两个dfs专题,c/c++版本,也讲思路。
思路:
结点不多,如果强行建树,应该也可以,不过巨麻烦。
后序遍历,即“左右根”,最后一个就是根结点,但是只能明显看出来第一个根节点
后续的根节点就只能去判断左子树右子树节点个数,进而判断左右根节点(暴力)
我选择的是递归建树,先往左子树搜索,到底部(没有左子树了)之后,每一次回溯会进入右子树,当右子树到底之后(没有右子树了),将结点存入相应的位置。
AcCode:
#include<bits/stdc++.h>
using namespace std;
int tree[40], back[40], cnt = 1, N;
void dfs(int idx){
if(idx > N) return ;
dfs(idx * 2);
dfs(idx * 2 + 1);
tree[idx] = back[cnt++];
}
int main(){
cin >> N;
for(int i = 1; i <= N; i++){
cin >> back[i];
}
dfs(1);
for(int i = 1; i <= N; i++){
cout << tree[i];
if(i != N) cout << " ";
}
return 0;
}