遍历二叉树, 是指按一定的规则和顺序访问二叉树的所有结点, 使每一个结点都被访问一次, 而且只被访问一次.
由于二叉树是非线性结构, 因此, 二叉树的遍历实质上是将二叉树的各个结点排列成一个线性序列.
DFS: 前序, 中序及后序.
BFS: 是指沿着二叉树的宽度优先遍历二叉树的结点, 即从上到下从左到右逐层遍历二叉树的结点.
访问根结点(N), 前序遍历左子树(L), 前序遍历右子树®, 也即NLR.
也可以是NRL, 因为这两种遍历方法都是先访问根结点, 所以没有区别, 掌握其中一种, 另一种也随之掌握.
给你二叉树的根节点
root
,返回它节点值的 前序 遍历。
非递归思路: 二叉树的前序遍历
// 二叉树的前序非递归遍历vector preorderTraversal(TreeNode* root) {stack st;vector v;TreeNode* curr=root;while(curr!=nullptr||!st.empty()){ while(curr!=nullptr){v.push_back(curr->val);st.push(curr);curr=curr->left;}TreeNode* top=st.top();st.pop();curr=top->right;/*// 当curr为空时,遍历左路结点的右子树if(curr==nullptr){TreeNode* top=st.top();st.pop();curr=top->right;}else // 当curr不为空时,遍历左路结点{v.push_back(curr->val);st.push(curr);curr=curr->left;}*/}return v;}
中序遍历左子树, 访问根结点, 中序遍历右子树, 也即LNR.
或者RNL.
给定一个二叉树的根节点
root
,返回 它的 中序 遍历 。
非递归思路: 二叉树的中序遍历
vector inorderTraversal(TreeNode* root) {std::vector v;std::stack st;TreeNode* curr=root;// 思路与前序遍历相似while(curr!=nullptr || !st.empty()){while(curr!=nullptr){st.push(curr);curr=curr->left;}TreeNode* top=st.top();st.pop();// 只是访问TreeNode的val时机不同v.push_back(top->val);curr=top->right;}return v;// vector v;// stack st;// TreeNode* curr=root;// while(curr!=nullptr || !st.empty())// {// if(curr!=nullptr)// {// st.push(curr);// curr=curr->left;// }// else// {// TreeNode* top=st.top();// st.pop();// v.push_back(top->val);// curr=top->right;// }// }// return v;}
**后序遍历左子树, 后序遍历右子树, 访问根结点, 也即LRN. **
或者RLN.
给你一棵二叉树的根节点
root
,返回其节点值的 后序遍历 。
非递归思路: 二叉树的后序遍历
vector postorderTraversal(TreeNode* root) {TreeNode* curr=root;TreeNode* prev=nullptr; // 记录遍历结点的前一个vector v;stack st;while(curr!=nullptr || !st.empty()){while(curr!=nullptr){st.push(curr); // 将结点入栈curr=curr->left;}TreeNode* top=st.top();// 当右子树为空或者右子树被访问过,才popif(top->right==nullptr || top->right==prev){prev=top;v.push_back(top->val);st.pop();}else // 否则先访问右子树,等右子树访问完成,才反过来访问根,不能pop{curr=top->right;}} /*while(curr!=nullptr|| !st.empty()){if(curr!=nullptr){st.push(curr);curr=curr->left;}else{TreeNode* top=st.top();// 当右子树为空或者右子树被访问过,才popif(top->right==nullptr || top->right==prev){ v.push_back(top->val);st.pop();prev=top;}else{curr=top->right;}}}*/return v;}
层序遍历就是根据二叉树的结构从上到下从左到右逐层遍历二叉树的结点.
给你二叉树的根节点
root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
基本思路: 二叉树的层序遍历
需要注意: 当某一层走完时, 该层的下一层也随之全部进入队列中.
vector> levelOrder(TreeNode* root) {queue q;vector> vv;int levelSize=0; // 记录某一层有多少个结点if(root!=nullptr){q.push(root);++levelSize; // 刚开始根结点这一层就一个结点}while(!q.empty()){vector v;// 将该层的结点都遍历完for(size_t i=0;iTreeNode* front=q.front();q.pop();v.push_back(front->val);if(front->left!=nullptr){q.push(front->left);}if(front->right!=nullptr){q.push(front->right);}}// 遍历完成,队列中的个数就是下一层结点的个数levelSize=q.size(); vv.push_back(v);}return vv;}if(front->right!=nullptr){q.push(front->right);}}// 遍历完成,队列中的个数就是下一层结点的个数levelSize=q.size(); vv.push_back(v);}return vv;}