二叉树的非递归遍历
非递归前序遍历
//非递归前序遍历:根-》左-》右,要点:用栈,先打印栈顶元素,出栈,先右进,再左进
void traverseNodeInTreePreOrderNonRecrusive(TreeNode *root)
{
if (root == NULL)
return;
stack<TreeNode *> dataStack;
dataStack.push(root);
while (!dataStack.empty())
{
TreeNode *topNode = dataStack.top();
cout << topNode->value << ",";
dataStack.pop();
if (topNode->rightChild != NULL)
{
dataStack.push(topNode->rightChild);
}
if (topNode->leftchild != NULL)
{
dataStack.push(topNode->leftchild);
}
}
cout << endl;
}
非递归中序遍历
思路:
1、声明一个栈,把根节点压栈。声明一个标志位,表示是否有节点刚压入过栈;
2、访问栈顶元素,若栈顶元素是刚压入的,说明栈顶元素的左孩子没有压入过栈,那么可以压入栈顶元素的左孩子;
3、若栈顶元素不是是刚压入的,说明栈顶元素的左孩子已经压入进栈,且已出栈;或者左孩子为空。按照中序遍历规则:左-》根-》右,则弹出栈顶元素,并打印;
4、若栈顶元素的右孩子不为空,则压入栈中;
5、循环2-4,直到栈为空,遍历完毕。
//非递归中序遍历:左-》根-》右
void traverseNodeInTreeInOrderNonRecrusive(TreeNode *root)
{
if (root == NULL)
return;
stack<TreeNode *> dataStack;
dataStack.push(root);
bool isAdd = true;
while (!dataStack.empty())
{
TreeNode *topNode = dataStack.top();
if (isAdd && topNode->leftchild != NULL)
{
dataStack.push(topNode->leftchild);
isAdd = true;
continue;
}
if (isAdd == false || topNode->leftchild == NULL)
{
cout << topNode->value << ",";
dataStack.pop();
isAdd = false;
}
if (topNode->rightChild != NULL)
{
dataStack.push(topNode->rightChild);
isAdd = true;
}
}
cout << endl;
}
非递归后续遍历
思路:
1、采用非递归前序遍历中类似的结构,先压根节点的右孩子,再压根节点的左孩子(出栈打印的顺序就是左孩子-》右孩子)。但跟前序遍历的打印顺序不同,前序遍历先打印根节点,再压栈;而这里是先压栈,再打印;
2、打印栈顶元素的条件是左右孩子都为空,或者左右孩子都已经打印了(说明该节点是根节点,左右孩子都打印了,就可以打印根节点),所以用一个指针指向最后打印的节点,可以防止重复压栈;
//非递归后序遍历:左-》右-》根
void traverseNodeInTreePostOrderNonRecrusive(TreeNode *root)
{
if (root == NULL)
return;
stack<TreeNode *> dataStack;
dataStack.push(root);
TreeNode *pLastNode = root;
while (!dataStack.empty())
{
TreeNode *topNode = dataStack.top();
if ((topNode->leftchild == pLastNode || topNode->rightChild == pLastNode) || (topNode->leftchild == NULL && topNode->rightChild == NULL))
{
cout << topNode->value << ",";
dataStack.pop();
pLastNode = topNode;
continue;
}
if (topNode->rightChild != NULL)
{
dataStack.push(topNode->rightChild);
}
if (topNode->leftchild != NULL)
{
dataStack.push(topNode->leftchild);
}
}
cout << endl;
}