二叉树的后续遍历
二叉树是很有用的一种数据结构,遍历则是其基本操作,这里列出实是保证完整性。二叉树后序遍历的非递归遍历中当当前节点存在右子树的时候需要先遍历右子树,因此要对二叉树的节点定义中添加_tag域,标志当前节点右子树是否已经遍历,备用的结构定义和函数:
//二叉树节点定义
class TreeNodeElement
{
public:
TreeNodeElement();
TreeNodeElement(int value);
TreeNodeElement(int value,TreeNodeElement* l,TreeNodeElement* r);
~TreeNodeElement();
private:
public:
int _value;
TreeNodeElement* _l;
TreeNodeElement* _r;
bool _tag;
};
typedef TreeNodeElement* TreeNode;
//构造函数的定义,前序和中序中相似,只是不需要_tag域
TreeNodeElement::TreeNodeElement()
{
_value = -1;
_l = NULL;
_r = NULL;
_tag = false;
}
TreeNodeElement::TreeNodeElement(int value)
{
_value = value;
_l = NULL;
_r = NULL;
_tag = false;
}
TreeNodeElement::TreeNodeElement(int value,TreeNodeElement* l,TreeNodeElement* r)
{
_value = value;
_l = l;
_r = r;
_tag = false;
}
//析构函数
TreeNodeElement::~TreeNodeElement()
{
delete _l;
delete _r;
}
class TreeNodeElement
{
public:
TreeNodeElement();
TreeNodeElement(int value);
TreeNodeElement(int value,TreeNodeElement* l,TreeNodeElement* r);
~TreeNodeElement();
private:
public:
int _value;
TreeNodeElement* _l;
TreeNodeElement* _r;
bool _tag;
};
typedef TreeNodeElement* TreeNode;
//构造函数的定义,前序和中序中相似,只是不需要_tag域
TreeNodeElement::TreeNodeElement()
{
_value = -1;
_l = NULL;
_r = NULL;
_tag = false;
}
TreeNodeElement::TreeNodeElement(int value)
{
_value = value;
_l = NULL;
_r = NULL;
_tag = false;
}
TreeNodeElement::TreeNodeElement(int value,TreeNodeElement* l,TreeNodeElement* r)
{
_value = value;
_l = l;
_r = r;
_tag = false;
}
//析构函数
TreeNodeElement::~TreeNodeElement()
{
delete _l;
delete _r;
}
访问函数:
//递归实现(visit)
void Visit(TreeNode node)
{
cout<<node->_value<<" ";
}
void Visit(TreeNode node)
{
cout<<node->_value<<" ";
}
二叉树后序遍历的递归实现:
//递归遍历
void PostRetriveATree(TreeNode root,void (* visit)(TreeNode))
{
if (root)
{
PostRetriveATree(root->_l,visit);
PostRetriveATree(root->_r,visit);
(*visit)(root);
}
}
void PostRetriveATree(TreeNode root,void (* visit)(TreeNode))
{
if (root)
{
PostRetriveATree(root->_l,visit);
PostRetriveATree(root->_r,visit);
(*visit)(root);
}
}
二叉树后序遍历的非递归实现:
//非递归遍历,添加#include <stack>
void PostRetriveATreeWithoutRecurve(TreeNode root,void (* visit)(TreeNode))
{
stack<TreeNode> tree;
while ((root != NULL) || (!tree.empty()))
{
while (root != NULL)
{
tree.push(root);
root = root->_l;
}
if (!tree.empty())
{
root = tree.top();
if (root->_tag) //可以访问
{
visit(root);
tree.pop();
root = NULL; //第二次访问标志其右子树也已经遍历
}
else
{
root->_tag = true;
root = root->_r;
}
}
}
}
void PostRetriveATreeWithoutRecurve(TreeNode root,void (* visit)(TreeNode))
{
stack<TreeNode> tree;
while ((root != NULL) || (!tree.empty()))
{
while (root != NULL)
{
tree.push(root);
root = root->_l;
}
if (!tree.empty())
{
root = tree.top();
if (root->_tag) //可以访问
{
visit(root);
tree.pop();
root = NULL; //第二次访问标志其右子树也已经遍历
}
else
{
root->_tag = true;
root = root->_r;
}
}
}
}