二叉树的前序遍历
递归实现
递归实现没什么好说的。个人感觉将函数功能看成一个整体,不要去想栈中怎么实现的。毕竟自己的脑袋不是电脑,绕着绕着就蒙了。
void preordered_traversal_recursion(TreeNode* root)
{
if(root == NULL) return;
container.push_back(root->val);
preordered_traversal_recursion(root->left);
preordered_traversal_recursion(root->right);
}
迭代实现
迭代通过栈来实现,具体过程如下图所示。
函数实现:
void preordered_traversal_iteration(TreeNode* root)
{
stack<TreeNode*> tree_s;
if(root == NULL) return;
tree_s.push(root);
while(!tree_s.empty())
{
TreeNode* node = tree_s.top();
tree_s.pop();
// 取出中间节点的值
container.push_back(node->val);
// 右节点
if(node->right) tree_s.push(node->right);
// 左节点
if(node->left) tree_s.push(node->left);
}
return;
}
二叉树的后序遍历
递归
void postordered_traversal_recursion(TreeNode* root)
{
if(root == NULL) return;
postordered_traversal_recursion(root->left);
postordered_traversal_recursion(root->right);
container.push_back(root->val);
}
迭代
后序遍历的顺序为左右中。在不知道中间节点的情况下无法获得左、右节点。因此先遍历中右左,然后reverse一下就行了。
函数实现:
void postordered_traversal_iteration(TreeNode* root)
{
stack<TreeNode*> tree_s;
if(root == NULL) return;
tree_s.push(root);
while (!tree_s.empty())
{
TreeNode* node = tree_s.top();
tree_s.pop();
container.push_back(node->val);
if(node->left) tree_s.push(node->left);
if(node->right) tree_s.push(node->right);
}
reverse(container.begin(),container.end());
return;
}
二叉树的中序遍历
递归
void inordered_traversal_recursion(TreeNode* root)
{
if(root == NULL) return;
inordered_traversal_recursion(root->left);
container.push_back(root->val);
inordered_traversal_recursion(root->right);
}
迭代
中序遍历的迭代比较麻烦。因为其遍历顺序为左中右。在不知道中间节点的情况下,无法取出左节点的值。
迭代的基本思想是:1)将左侧的节点全部压入栈中。2)取出栈顶元素,即最左下角的节点。3)判断该节点有没有右节点,有右节点的话,压入栈中,然后重复1),2)。没有的话,继续弹出栈顶元素。
看下面的图可能会比较好理解。
函数实现:
void inordered_traversal_iteration(TreeNode* root)
{
stack<TreeNode*> tree_s;
if(root == NULL) return;
while(!tree_s.empty() || root != NULL)
{
// 将左侧节点全部压入栈中,找到最左侧的节点
while(root != NULL)
{
tree_s.push(root);
root = root->left;
}
// 取出最左侧的节点
root = tree_s.top();
tree_s.pop();
container.push_back(root->val);
// 从最左侧节点的右节点开始新的一轮遍。
root = root->right;
}
}