目录
二叉树大家都非常熟悉,二叉树的遍历大家也不会陌生。用递归法来实现二叉树的“前中后序遍历”相对简洁,用几行代码就能实现,并且只需改变代码顺序就能实现3种遍历。与之相反,非递归(迭代)遍历方法实现“前中后序遍历”起来较为复杂,并且不太容易通过简单的交换代码的次序来实现3种遍历,当然,只是不太容易,并不是没有方法。 下面就介绍统一的非递归(迭代)方法来是实现“前中后序遍历”。
这个过程要使用栈的数据结构,这点想来不用多解释。
树节点的定义如下:
template<class T>
class TreeNode
{
public:
T data;
TreeNode* leftChild;
TreeNode* rightChild;
};
首先明确一点:树中的任何一个节点都可以是父节点
。每个父节点总是有左右两个子节点(空的子节点暂时也算是一个节点)。做遍历时,按照遍历的方式,依次把父节点和左右两个子节点压入栈中。此处以“后序遍历”为例,那么入栈的顺序就是父节点、右节点、左节点,按照思路,可以写出如下代码:
void BinaryTree<T>::PostOrderIterate(TreeNode<T> * node)
{
std::stack<TreeNode<T> *> st;//定义一个栈
TreeNode<T> * curnode = node;
if (curnode == nullptr) return;
//将父节点和两个子节点压入栈中,若子节点没有,不用压入栈
st.push(curnode);
if (curnode->rightChild) st.push(curnode->rightChild);
if (curnode->leftChild) st.push(curnode->leftChild);
while (!st.empty()){
//每次top出的栈顶数据可能是父节点或子节点。但是,不管哪种节点,现在都作为一个父节点,那么其入栈顺序要变,所以pop掉,重新入栈
curnode = st.top();
st.pop();
//按遍历顺寻入栈
st.push(curnode);
if (curnode->rightChild) st.push(curnode->rightChild);
if (curnode->leftChild) st.push(curnode