赞
踩
目录
二叉树:一个节点只有一个入度和至多两个出度的图。
遍历方式:树/图的遍历分为深度优先搜索(DFS和广度优先遍历(BFS)。一般来说深度优先搜索的特点决定了深度优先搜索依赖于栈的实现,而广度优先搜索的实现依赖于队列的实现。
关键词:递归、栈
顺序:先根节点、然后左子树、右子树
- //递归版本
- void traversal(TreeNode* root, vector<int>& res) {
- if(root == nullptr)
- return;
- res.emplace_back(root->val);
- traversal(root->left, res);
- traversal(root->right, res);
- }
- vector<int> preorderTraversal(TreeNode* root) {
- vector<int> res;
- traversal(root, res);
- return res;
- }
-
- //非递归实现使用栈来保存遍历过的节点,不断入栈出栈直到栈空为止。 非递归实现与递归实现不同,遍历根节点后要先遍历右子树再遍历左子树(因栈的后进先出特性)
- vector<int> preorderTraversal(TreeNode* root) {
- vector<int> res;
- if(root == nullptr)
- return res;
- stack<TreeNode*> st;
- st.push(root);
- while (!st.empty()) {
- auto node = st.top();
- res.push_back(node->val);
- st.pop();
- if(node->right != nullptr)
- st.push(node->right);
- if(node->left != nullptr)
- st.push(node->left);
- }
- return res;
- }
顺序:左子树--根节点--右子树
- #递归版本
- void travesal(TreeNode* root, vector<int>& res){
- if(!root)
- return;
- travesal(root->left,res);
- res.push_back(root->val);
- travesal(root->right, res);
- }
- vector<int> inorderTraversal(TreeNode* root) {
- vector<int> res;
- travesal(root, res);
- return res
- }
-
- #非递归实现,使用栈保存遍历过的节点,先找到最左节点然后依次出栈遍历节点对应的右子节点:
- vector<int> inorderTraversal(TreeNode* root) {
- vector<int> res;
- stack<TreeNode*> st;
- while (root != nullptr || !st.empty()) {
- while (root != nullptr) {
- st.push(root);
- root = root->left;
- }
- root = st.top();
- st.pop();
- res.push_back(root->val);
- root = root->right;
- }
- return res;
- }
顺序:左子树--右子树--根节点
- #递归版本
- void traversal(TreeNode* root, vector<int>&res){
- if(root == nullptr)
- return;
- traversal(root->left, res);
- traversal(root->right, res);
- res.push_back(root->val);
- }
- vector<int> postorderTraversal(TreeNode* root) {
- vector<int> res;
- traversal(root, res);
- return res;
- }
-
- #非递归实现,使用栈保存遍历过的节点,先找到最右节点然后依次出栈遍历节点对应的左子节点,最后需要反转遍历结果:
- vector<int> postorderTraversal(TreeNode* root) {
- vector<int> res;
- if(root == nullptr)
- return res;
- stack<TreeNode*> st;
- TreeNode* prev = nullptr;
- while (!st.empty() || root != nullptr) {
- while(root != nullptr) {
- res.push_back(root->val);
- st.push(root);
- root = root->right;
- }
- root = st.top()->left;
- st.pop();
- }
- reverse(res.begin(), res.end());
- return res;
- }
二叉树的广度优先搜索类似于层序遍历:遍历跟节点,遍历左子节点和右子节点,然后遍历左子节点和它的左右子节点以及右子节点和它的左右子节点。广度优先搜索严格按照遍历的先后循序遍历节点,符合队列先进先出(FIFO)的特点,适合使用队列来实现。
- void bfs(TreeNode* root) {
- if(!root)
- return;
- queue<TreeNode*> que;
- que.push(root);
- while(!que.empty()){
- auto node = que.front();
- que.pop();
- cout << node->val << endl;
- if(node->left) que.push(node->left);
- if(node->right) que.push(node->right);
- }
- return res;
- }
不同点:需要对每层做一个标记
- #跟节点入队后加入一个空节点做哨兵,出队的时候发现是空节点就知道一层遍历结束了,保存本层结果继续加入空节点做哨兵。
- vector<vector<int>> levelOrder(TreeNode* root) {
- vector<vector<int>> res;
- if(!root)
- return res;
- queue<TreeNode*> que;
- que.push(root);
- que.push(nullptr);
- vector<int> temp;
- while(!que.empty()){
- auto node = que.front();
- que.pop();
- if(node){
- temp.push_back(node->val);
- if(node->left) que.push(node->left);
- if(node->right) que.push(node->right);
- }else if(!temp.empty()){
- res.push_back(temp);
- temp.clear();
- que.push(nullptr);
- }
- }
- return res;
- }
路子:3.2自顶向下遍历后,逆置一下数组
- vector<vector<int>> levelOrderBottom(TreeNode* root) {
- vector<vector<int>> res;
- if(root == nullptr)
- return res;
- queue<TreeNode*> que;
- que.push(root);
- que.push(nullptr);
- vector<int> temp;
- while(!que.empty()){
- auto node = que.front();
- que.pop();
- if(node){
- temp.push_back(node->val);
- if(node->left) que.push(node->left);
- if(node->right) que.push(node->right);
- }else if(!temp.empty()){
- res.push_back(temp);
- temp.clear();
- que.push(nullptr);
- }
- }
- reverse(res.begin(), res.end());
- return res;
- }
路子:只需要在层序遍历基础上加上一个标志,需要逆序时逆置一下该层遍历结果就可以了。
- vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
- vector<vector<int>> res;
- if(!root)
- return res;
- queue<TreeNode*> que;
- que.push(root);
- que.push(nullptr);
- vector<int> temp;
- bool change = false;
- while(!que.empty()){
- auto node = que.front();
- que.pop();
- if(node){
- temp.push_back(node->val);
- if(node->left) que.push(node->left);
- if(node->right) que.push(node->right);
- }else if(!temp.empty()){
- if(change)
- reverse(temp.begin(), temp.end());
- res.push_back(temp);
- temp.clear();
- que.push(nullptr);
- change = !change;
- }
- }
- return res;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。