题目:
给定一棵二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号。下面是一个例子:
输出:
1
2 3
4 5 6
7 8
代码:
结构体的定义:
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(NULL), right(NULL){
}
};
解法一:
先是我自己第一次做的,我是利用先序遍历的递归算法,再加一个二维数组存储结果实现的。
void levelOrder(TreeNode* root, int lev,vector<vector<int>>& vec){
if (root != NULL){
if (vec.size() == lev){
vector<int> v;
vec.push_back(v);
}
vec[lev].push_back(root->val);
levelOrder(root->left,lev+1,vec);
levelOrder(root->right,lev+1,vec);
}
}
void printNodeByLevelOrder(TreeNode* root){
if (root == NULL){
return;
}
vector<vector<int>> vec;
levelOrder(root, 0, vec);
int lev = vec.size();
for (int i = 0; i < lev; i++){
for (int j = 0; j < vec[i].size(); j++){
cout << vec[i][j] << " ";
}
cout << endl;
}
}
解法二:
书上的数组非递归解法:
从根节点出发,依次将每层的节点从左到右压入一个数组,并用一个游标cur记录当前访问的节点,另一个游标last指示当前层次的最后一个节点的下一个位置。当cur==last,当前层次访问结束。
oid printNodeByLevelOrder_Nonrecursive(TreeNode* root){
if (root == NULL){
return;
}
vector<TreeNode*> vec;
vec.push_back(root);
int cur = 0;
int last;
while (cur < vec.size()){
last = vec.size();
while (cur < last){
cout << vec[cur]->val << " ";
if (vec[cur]->left != NULL){
vec.push_back(vec[cur]->left);
}
if (vec[cur]->right != NULL){
vec.push_back(vec[cur]->right);
}
cur++;
}
cout << endl;
}
}
解法三:
还有种利用queue来做的。相当于BFS的一种变形,不过如果直接用队列BFS来做的话,不能分层。所以要加入一个结束信号,代表这一层的访问结束,即可作为是这一层的最后一个节点。
void printNodeByLevelOrder_BFS(TreeNode* root){
queue<TreeNode*> q;
q.push(root);
q.push(NULL);
while (!q.empty()){
TreeNode* tmp = q.front();
q.pop();
if (tmp == NULL){
cout << endl;
continue;
}
cout << tmp->val << " ";
if (tmp->left != NULL){
q.push(tmp->left);
}
if (tmp->right != NULL){
q.push(tmp->right);
}
//对于每一层的最后一个节点,它的子节点也是下一层的最后一个节点
if (q.front() == NULL){
q.push(NULL);
}
}
}
扩展问题:
如果要求按深度从下到上访问图中的二叉树,每层的访问顺序仍然是从左到右,即访问顺序变为:
78
456
23
1
代码:
void printNodeByLevelOrderBottom_Nonrecursive(TreeNode* root){
vector<TreeNode*> vec;
int cur = 0;
int last;
vec.push_back(root);
while (cur < vec.size()){
vec.push_back(NULL);
last = vec.size();
while (cur < last){
if (vec[cur] && vec[cur]->left != NULL){
vec.push_back(vec[cur]->left);
}
if (vec[cur] && vec[cur]->right != NULL){
vec.push_back(vec[cur]->right);
}
cur++;
}
}
for (int i = vec.size() - 1; i >= 0; i--){
if (vec[i] == NULL){
cout << endl;
}
else{
cout << vec[i]->val << " ";
}
}
}