关于二叉树的遍历在面试时是企业常常容易考到的题目,这里作一下总结。面试
二叉树有前序遍历,中序遍历和后序遍历三种。关于这三种遍历,网上资料有不少,在此就不作详细介绍了。主要须要记住顺序:函数
递归时仅须要按照上述顺序就能够了。post
void preOrder(TreeNode* root) { if (!root) { return; } cout << root->val; preOrder(root->left); preOrder(root->right); }
void inOrder(TreeNode* root) { if (!root) { return; } inOrder(root->left); cout << root->val; inOrder(root->right); }
void postOrder(TreeNode* root) { if (!root) { return; } postOrder(root->left); postOrder(root->right); cout << root->val; }
可见递归版本实现起来很是简单,面试的时候,每每面试官会强制你写出非递归的版本,网上关于非递归版本的介绍也有不少,这里我分享一个本身认为是比较好记的版本。spa
显然,咱们须要用一个stack来模拟递归时的函数调用。对于三种遍历,咱们都使用push当前节点->push左子树->pop左子树->push右子树->pop右子树的方式。可是cout时机会有所不一样。指针
对于前序遍从来说,每次访问到一个节点就cout;code
对于中序遍从来说,每次将右子节点进栈时,把当前节点cout;blog
对于后序遍从来说,每次pop的时候cout。递归
另外咱们还须要一个last_pop指针来存放上一个pop出去的节点。it
若是当前节点的左右节点都不是上一个pop的节点,那么咱们将左子节点入栈;ast
若是当前节点的左节点是上一个pop的节点,但右节点不是,那么就把右子节点入栈;
不然的话,就须要让当前节点出栈。
大体思路就是这样,俗话说Talk is cheap, let's coding. 直接上代码,注意三种遍历的代码整体结构都是彻底同样的,只是cout的时机有所不一样。
void preorder_traversal_iteratively(TreeNode* root) { if (root == 0) return; stack<TreeNode*> s; s.push(root); cout << root->val << ' '; // visit root TreeNode* last_pop = root; while (!s.empty()) { TreeNode* top = s.top(); if (top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left { s.push(top->left); cout << top->left->val << ' '; // visit top->left } else if (top->right != 0 && top->right != last_pop && (top->left == 0 || top->left == last_pop)) // push_right { s.push(top->right); cout << top->right->val << ' '; // visit top->right } else // pop { s.pop(); last_pop = top; } } }
void inorder_traversal_iteratively(TreeNode* root) { if (root == 0) return; stack<TreeNode*> s; s.push(root); TreeNode* last_pop = root; while (!s.empty()) { TreeNode* top = s.top(); if (top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left { s.push(top->left); } else if (top->right != 0 && top->right != last_pop && (top->left == 0 || top->left == last_pop)) // push_right { s.push(top->right); cout << top->val << ' '; // visit top } else // pop { s.pop(); last_pop = top; if (top->right == 0) cout << top->val << ' '; // visit top } } }
void postorder_traversal_iteratively(TreeNode* root) { if (root == 0) return; stack<TreeNode*> s; s.push(root); TreeNode* last_pop = root; while (!s.empty()) { TreeNode* top = s.top(); if (top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left { s.push(top->left); } else if (top->right != 0 && top->right != last_pop && (top->left == 0 || top->left == last_pop)) // push_right { s.push(top->right); } else // pop { s.pop(); last_pop = top; cout << top->val << ' '; // visit top } } }