前序遍历
根–左--右
public T preorderTraversal(TreeNode root) {
Stack<TreeNode> nodes = new Stack();
TreeNode node = root;
while(true){
/*-------------*/
visit(node);
/*-------------*/
if(node.right!=null){
nodes.add(node.right);
}
if(node.left!=null){
nodes.push(node.left);
}
if(nodes.isEmpty())break;
node = nodes.pop();
}
//return res;
}
中序遍历
左–根--右
public T inorderTraversal(TreeNode root) {
Stack<TreeNode> nodes = new Stack();
TreeNode node = root;
while(true){
//当前结点所有左子树全部入栈
while(node!=null){
nodes.add(node);
node=node.left;
}
//如果node为null,nodes为null,结束遍历
if(nodes.isEmpty())break;
node = nodes.pop();
/*-------------*/
visit(node);
/*-------------*/
node = node.right;
}
}
后续遍历
(根)–左--右–根
后续遍历中根节点需要经过两次,对根节点的相关操作是在第二次遍历的时候才开始的。第一次遍历根节点时,就是将当前根节点的左右节点压入栈中。
利用两次入栈来解决两次经过节点。
public T postorderTraversal(TreeNode root) {
Stack<TreeNode> nodes = new Stack();
TreeNode node = root;
while(true){
while(node!=null){
//入栈两次,是因为节点需要经过两次
nodes.push(node);
nodes.push(node);
node = node.left;
}
if(nodes.isEmpty())break;
//当node为null时,执行pop();
node = nodes.pop();
//如果此时nodes不为null,且当前节点是第一次遍历到(node==nodes.peek()),则循环当前节点的right。
if(!nodes.isEmpty()&&node==nodes.peek()){//第一次访问{
node = node.right;
}else{
//如果在执行pop()后,nodes为null,表示当前node为root,直接执行vistied(node)
//如果是第二次访问,此时需要执行visited(node)
/*-------------*/
visit(node);
/*-------------*/
node = null;
}
}
//return res;
}