前序遍历
非递归先序遍历的思路如下:
1.先将根节点入栈
2.访问根节点
3.如果根节点存在右孩子,则将右孩子入栈
4.如果根节点存在左孩子,则将左孩子入栈(注意:一定是右孩子先入栈,然后左孩子入栈)
5.重复2-4
--非递归
public void preOrder(TreeNode root){
Stack<TreeNode> stack = new LinkedList();
stack.push(root);
TreeNode curr;
while(!stack.isEmpty()){
curr = stack.pop();
System.out.print(curr.data());
if(curr.right!=null){
stack.push(curr.right);
}
if(curr.left!=null){
stack.push(curr.left);
}
}
}
--递归版
public void preOrder(TreeNode root){
if(root!=null){
System.out.print(root.data());
preOrder(root.left);
preOrder(root.right);
}
}
中序遍历
非递归中序遍历的思路如下:
1.先将根节点入栈
2.将当前节点的所有左孩子入栈,直到左孩子为空
3.访问栈顶元素,如果栈顶元素存在右孩子,则继续第2步
4.重复第2、3步,直到栈为空并且所有的节点都被访问
--非递归
public void inOrder(TreeNode root){
Stack<TreeNode> stack = new LinkedList();
TreeNode curr=root;
while(!stack.isEmpty()||curr!=null){
while(curr!=null){
stack.push(curr);
curr=curr.left;
}
if(!stack.isEmpty()){
curr=stack.pop();
System.out.print(curr.data());
curr=curr.right;
}
}
}
--递归版
public void inOrder(TreeNode root){
if(root!=null){
preOrder(root.left);
System.out.print(root.data());
preOrder(root.right);
}
}
后续遍历
后续遍历的非递归实现思路:
1.根节点入栈
2.将根节点的左子树入栈,直到最左,没有左孩子为止
3.得到栈顶元素的值,先不访问,判断栈顶元素是否存在右孩子,如果存在并且没有被访问,则将右孩子入栈,否则,就访问栈顶元素
--非递归
public void inOrder(TreeNode root){
Stack<TreeNode> stack = new LinkedList();
TreeNode curr=root;
TreeNode rNode=null;
while(!stack.isEmpty()||curr!=null){
while(curr!=null){
stack.push(curr);
curr=curr.left;
}
curr = stack.pop();
//当前节点不为空,没有右孩子,或者右孩子已经被访问过
while (curr != null && (curr.right == null ||curr.right == rNode)) {
System.out.print(curr.data+" ");
rNode = curr;
if (stack.isEmpty()){
System.out.println();
return;
}
curr = stack.pop();
}
stack.push(curr);
curr = curr.right;
}
}
--递归版
public void postOrder(TreeNode root){
if(root!=null){
preOrder(root.left);
preOrder(root.right);
System.out.print(root.data());
}
}