# 二叉树遍历算法

#### 前中后序遍历的教科书式写法

    //非递归前序遍历
void preorderTraversal(TreeNode *root, vector<int> &path)
{
stack<TreeNode *> s;
TreeNode *p = root;
while(p != NULL || !s.empty())
{
while(p != NULL)
{
path.push_back(p->val);
s.push(p);
p = p->left;
}
if(!s.empty())
{
p = s.top();
s.pop();
p = p->right;
}
}
}
//非递归中序遍历
void inorderTraversal(TreeNode *root, vector<int> &path)
{
stack<TreeNode *> s;
TreeNode *p = root;
while(p != NULL || !s.empty())
{
while(p != NULL)
{
s.push(p);
p = p->left;
}
if(!s.empty())
{
p = s.top();
path.push_back(p->val);
s.pop();
p = p->right;
}
}
}
//非递归后序遍历-迭代
struct node{
int data;
node *left;
node *right;
};
struct BTNode{
node *btnode;
bool isfirst;
};
void postorderTraverse(node *root)
{
stack<BTNode *> s;
node *p = root;
BTNode *temp;
while (p != NULL || !s.empty())
{
while (p != NULL)
{
BTNode *btn = (BTNode *)malloc(sizeof(BTNode));
btn->btnode = p;
btn->isfirst = true;
s.push(btn);
p = p->left;
}
if (!s.empty())
{
temp = s.top();
s.pop();
if (temp->isfirst == true)
{
temp->isfirst = false;
s.push(temp);
p = temp->btnode->right;
}
else
{
cout << temp->btnode->data << " ";
p = NULL;
}
}
}
}

#### 前序遍历，中序遍历，后序遍历的通用解法（不太好理解，建议常规做法）

There is an universal idea for preorder traversal inorder traversal and postorder traversal. For each node N, we process it as follows:
——- push N in stack -> push left tree of N in stack -> pop left tree of N -> push right tree of N in stack -> pop right tree of N -> pop N———
For preorder traversal, we visit a node when pushing it in stack. For inorder traversal, we visit a node when pushing its right child in stack.
For postorder traversal, we visit a node when popping it. lastpop represents the node which is popped the last time. For the top node in stack,
it has three choices, pushing its left child in stack, or pushing its right child in stack, or being popped. If lastpop != top->left, meaning that its left tree has not been pushed in stack, then we push its left child. If last_pop == top->left, we push its right child. Otherwise, we pop the top node.

void preorder_traversal_iteratively(TreeNode* root )
{
if (root == 0 )
return;
stack<TreeNode *> s;
s.push (root);
cout << root ->val << ' ' ; // visit root
TreeNode* last_pop = root;
while (!s. empty())
{
TreeNode * top = s.top();
if ( top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left
{
s .push( top->left );
cout << top-> left->val << ' ' ; // visit top->left
}
else if (top->right != 0 && top->right != last_pop && (top ->left == 0 || top->left == last_pop)) // push_right
{
s .push( top->right );
cout << top-> right->val << ' ' ; // visit top->right
}
else // pop
{
s .pop();
last_pop = top;
}
}
}
void inorder_traversal_iteratively(TreeNode* root )
{
if (root == 0 )
return;
stack<TreeNode *> s;
s.push (root);
TreeNode* last_pop = root;
while (!s. empty())
{
TreeNode * top = s.top();
if ( top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left
{
s .push( top->left );
}
else if (top->right != 0 && top->right != last_pop && (top ->left == 0 || top->left == last_pop)) // push_right
{
s .push( top->right );
cout << top-> val << ' '; // visit top
}
else // pop
{
s .pop();
last_pop = top;
if ( top->right == 0 )
cout << top-> val << ' '; // visit top
}
}
}
void postorder_traversal_iteratively(TreeNode* root )
{
if (root == 0 )
return;
stack<TreeNode *> s;
s.push (root);
TreeNode* last_pop = root;
while (!s. empty())
{
TreeNode * top = s.top();
if ( top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left
{
s .push( top->left );
}
else if (top->right != 0 && top->right != last_pop && (top ->left == 0 || top->left == last_pop)) // push_right
{
s .push( top->right );
}
else // pop
{
s .pop();
last_pop = top;
cout << top-> val << ' '; // visit top
}
}
}

• 本文已收录于以下专栏：

## 二叉树遍历算法总结

• wp1603710463
• 2016年03月20日 18:43
• 2032

## 【每日算法】二叉树的遍历

• jiange_zh
• 2016年02月25日 00:17
• 1870

## 用java代码实现二叉树的遍历算法

• qq_27692191
• 2016年02月25日 20:27
• 453

## 二叉树的各种遍历算法以及实例

• shufac
• 2014年05月25日 23:36
• 19314

## Java实现二叉树三种遍历算法

• u014663362
• 2014年07月08日 17:05
• 6273

## C++二叉树的遍历总结

1、二叉树的存储结构      二叉树是非线性结构，即每个数据结点至多只有一个前驱，但可以有多个后继。它可采用顺序存储结构和链式存储结构。 (1)顺序存储结构      二叉树的顺序存储，就是用一...
• JIEJINQUANIL
• 2016年08月03日 22:33
• 750

## 二叉树遍历的递归、非递归算法（Java实现）

• apandi_
• 2016年10月24日 22:35
• 1867

## C++实现二叉树遍历

• anialy
• 2012年06月03日 01:57
• 9847

## 数据结构学习心得——二叉树的三种遍历算法

• u012350430
• 2017年09月29日 12:21
• 615

## java实现二叉树的三种遍历算法(递归)

java实现二叉树的三种遍历算法(递归)
• jiangfullll
• 2014年09月23日 16:18
• 5478

举报原因： 您举报文章：二叉树遍历算法总结 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)