思路:
1、使用广度优先遍历,将二叉树所有节点存放于一个双端队列中。
2、使用分隔符(空节点)将层级分离。
3、使用bool控制每一行的输出顺序即可。
执行用时:8 ms
内存消耗:11.5 MB
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void BFS(deque<TreeNode*>& deq, int& index)
{
while (index < deq.size())
{
TreeNode* cur = deq[index];
if (cur == nullptr && index == deq.size()-1)
return;
else if(cur == nullptr)
deq.push_back(nullptr);
else
{
if (cur->left)
deq.push_back(cur->left);
if (cur->right)
deq.push_back(cur->right);
}
index++;
}
}
void toVector(deque<TreeNode*>& deq,vector<vector<int>>& ret)
{
if(deq.size() <= 0) return;
bool forwardPrintf = true;
int index1 = 0;
int index2 = 0;
vector<int> vLayer;
while (index1 < deq.size()|| index2 < deq.size())
{
auto cur = deq[index2];
if (cur == nullptr)//翻转打印方向
{
if(forwardPrintf)
ret.push_back(vLayer);
else
{
int temp = index2 - 1;
while (index1 - 1 < temp)
{
vLayer.push_back(deq[temp]->val);
temp--;
}
ret.push_back(vLayer);
}
vLayer.clear();
index1 = index2;
index1++;
index2++;
forwardPrintf = !forwardPrintf;
}
else if (forwardPrintf)//直接打印
{
vLayer.push_back( cur->val);
index1++;
index2++;
}
else//index2先行
{
index2++;
}
}
}
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> ret;
if (root == nullptr)
return ret;
deque<TreeNode*> deq;
deq.push_back(root);
deq.push_back(nullptr);
int index = 0;
BFS(deq, index);
toVector(deq,ret);
return ret;
}
};
思路:
既然使用双端队列,那就可以直接在队首或者队尾进行增删。
正向打印时,遍历deque中从front开始的所有节点,将其左右子树按序放入队尾push_back;
当正向打印到达deque的第一个nullptr时,保存这之前遍历的元素,改变当前节点至队尾元素,改变遍历方向。
当反向打印时,遍历deque中end()–的元素,将其左右子树反序放入deque的首部push_front;
当反向打印到达deque的第一个nullptr时,保存这之前遍历的元素,pop当前nullptr,使当前节点成为deque的队首元素。
执行用时:4 ms
内存消耗:11.3 MB
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void BfsPro(deque<TreeNode*>& deq,bool bForword,vector<vector<int>>& ret)
{
vector<int> layer;
auto cur = deq.front();
while (deq.size())
{
if (bForword && cur == nullptr)
{
ret.push_back(layer);
layer.clear();
auto tmp = deq.end();
tmp--;
cur = *tmp;
if (deq.size() == 1 && cur == nullptr)
break;
bForword = !bForword;
}
else if (!bForword && cur == nullptr)
{
ret.push_back(layer);
layer.clear();
cur = deq.front();
if (deq.size() == 1 && cur == nullptr)
break;
bForword = !bForword;
}
else if (bForword && cur != nullptr)
{
layer.push_back(cur->val);
if (cur->left) deq.push_back(cur->left);
if (cur->right) deq.push_back(cur->right);
deq.pop_front();
cur = deq.front();
}
else if (!bForword && cur != nullptr)
{
layer.push_back(cur->val);
if (cur->right) deq.push_front(cur->right);
if (cur->left) deq.push_front(cur->left);
deq.pop_back();
auto tmp = deq.end();
tmp--;
cur = *(tmp);
}
}
}
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> ret;
if(root== nullptr)
return ret;
deque<TreeNode*> deq;
deq.push_back(root);
deq.push_back(nullptr);
bool bForword = true;
BfsPro(deq, bForword,ret);
return ret;
}
};
深度优先遍历
如果当前节点的双端队列不存在,则创建一个双端队列,并将该节点加入队列中。
如果当前节点的双端队列已经存在,则直接插入该队列中。
都递归当前节点的左右子节点。
输出时,需要根据层数,改变输出方向。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void Dfs(TreeNode* root, deque<deque<int>>& deq,int layer)
{
if (root == nullptr)
return;
if (layer < deq.size())
{
deq[layer].push_back(root->val);
}
else
{
deque<int> tmp;
tmp.push_back(root->val);
deq.push_back(tmp);
}
Dfs(root->left,deq, layer+1);
Dfs(root->right, deq, layer+1);
}
void dePrint(deque<deque<int>>& deq,vector<vector<int>>& ret)
{
vector<int> layer;
for (int i = 0; i < deq.size(); ++i)
{
if (i % 2 == 0)
{
while (deq[i].size())
{
layer.push_back(deq[i][0]);
deq[i].pop_front();
}
}
else
{
while (deq[i].size())
{
auto tmp = deq[i].end();
tmp--;
layer.push_back(*(tmp));
deq[i].pop_back();
}
}
ret.push_back(layer);
layer.clear();
}
}
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> ret;
if(root== nullptr)
return ret;
deque<deque<int>> deq;
Dfs( root, deq, 0);
dePrint( deq,ret);
return ret;
}
};
由于深度优先遍历时,无法输出结果,所以相比较而言,还是广度优先遍历的方法更优。