前序遍历
若二叉树非空,则执行以下操作:
(01) 先访问根节点;
(02) 先序遍历左子树;
(03) 先序遍历右子树。
递归
void preorder_bstree(BSTree tree)
{
if(tree != NULL)
{
printf("%d ", tree->key);
preorder_bstree(tree->left);
preorder_bstree(tree->right);
}
}
非递归
// 非递归方法 dfs
vector<int> preorderTraversal(TreeNode* root) {
if(root == NULL) return {};
vector<int> ans;
stack<TreeNode*> sck;
sck.push(root);
while(!sck.empty())
{
TreeNode * curr = sck.top();
sck.pop();
ans.push_back(curr->val);
if(curr->right != NULL) sck.push(curr->right);
if(curr->left != NULL) sck.push(curr->left);
}
return ans;
}
中序遍历
若二叉树非空,则执行以下操作:
(01) 中序遍历左子树;
(02) 访问根结点;
(03) 中序遍历右子树。
递归
void inorder_bstree(BSTree tree)
{
if(tree != NULL)
{
inorder_bstree(tree->left);
printf("%d ", tree->key);
inorder_bstree(tree->right);
}
}
非递归
从根节点开始对于每个当前遍历到的结点有:
- 当前节点为空,从栈中弹出节点并打印然后当前父节点的右子节点移动
- 否则不空的话,当前节点压入栈中,当期前节点向左子节点移动
vector<int> inorderTraversal(TreeNode* root) {
if(root == nullptr) {};
stack<TreeNode*> sck;
vector<int> v;
while(!sck.empty() || root)
{
if(root != nullptr)
{
sck.push(root);
root = root->left;
}
else
{
root = sck.top(); sck.pop();
v.push_back(root->val); // 保存输出的数
root = root->right;
}
}
return true;
}
后序遍历
若二叉树非空,则执行以下操作:
(01) 后序遍历左子树;
(02) 后序遍历右子树;
(03) 访问根结点。
递归
void postorder_bstree(BSTree tree)
{
if(tree != NULL)
{
postorder_bstree(tree->left);
postorder_bstree(tree->right);
printf("%d ", tree->key);
}
}
非递归
利用两个栈实现,具体实现过程可以顺着代码推一遍就能够理解了。
vector<int> posorderTraversal(TreeNode* root)
{
if(!root) return {};
stack<TreeNode*> s1,s2;
vector<int> v;
s1.push(root);
while(!s1.empty())
{
TreeNode* curr = s1.top();
s1.pop();
s2.push(curr); // 压入s2中
if(!curr->left) s1.push(curr->left);
if(!curr->right) s1.push(curr->right);
}
while(!s2.empty())
{
v.push_back(s2.top()->val);
s2.pop();
}
return v;
}
拓展: 如何用一个栈来实现二叉树后续遍历的非递归版?