二叉树的遍历(前序,中序,后序,层序)
前序遍历
中左右(先访问当前节点再访问左右孩子结点)
输入:root = [1,null,2,3]
输出:[1,2,3]
//迭代法
vector<int> traversal(TreeNode* root)
{
vector<int>res;
stack<TreeNode*> sta;
sta.push(root);
while(!sta.empty())
{
TreeNode* node=sta.top();//中
sta.pop();
res.push_back(node->val);
if(node->right!=NULL) sta.push(node->right);//右
if(node->left!=NULL) sta.push(node->left);//左
}
return res;
}
//递归法
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
vec.push_back(cur->val); // 中
traversal(cur->left, vec); // 左
traversal(cur->right, vec); // 右
}
中序遍历
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
左中右
输入:root = [1,null,2,3]
1
\
2
/
3
输出:[1,3,2]
//迭代法
vector<int>traversal(TreeNode* root)
{
vector<int>res;
stack<TreeNode*>sta;
if(root==NULL) return res;
TreeNode* cur=root;
while(cur||!sta.empty())
{
//不断遍历左子树
if(cur!=NULL)
{
sta.push(cur);
cur=cur->left; //左
}
else
{
// 从栈里弹出的数据,就是要处理的数据(放进result数组里的数据)
cur=sta.top();//中
sta.pop();
res.push_back(cur->val);
cur=cur->right;//右
}
}
return res;
}
//递归法
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
traversal(cur->left, vec); // 左
vec.push_back(cur->val); // 中
traversal(cur->right, vec); // 右
}
后续遍历
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
左右中
//迭代法
vector<int> postorderTraversal(TreeNode* root) {
vector<int>res;
stack<TreeNode*>s;
TreeNode* cur=root;
TreeNode* pre=NULL;
while(cur||!s.empty())
{
同样是不断遍历左子树
while(cur)
{
s.push(cur);
cur=cur->left;
}
cur=s.top();
//当该节点的右子树为空或者该节点的右节点是上次遍历过的节点,则直接弹出
if(cur->right==NULL||cur->right==pre)
{
res.push_back(cur->val);
pre=cur;
//当弹出一个节点时,说明该树已经遍历完了,那么就要把cur设置为NULL
//这样的话进行下一轮的循环正好进入
cur=NULL;
s.pop();
}
else
cur=cur->right;
}
return res;
}
//递归法
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
traversal(cur->left, vec); // 左
traversal(cur->right, vec); // 右
vec.push_back(cur->val); // 中
}
层序遍历
层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。
vector<vector<int>> traversal(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
vector<vector<int>> result;
while (!que.empty()) {
int size = que.size();
vector<int> vec;
// 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
result.push_back(vec);
}
return result;
}