后续遍历的非递归不好理解
其他的都还好
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class TreeNode1 {
public static class TreeNode{
int val;
TreeNode right;
TreeNode left;
public TreeNode(){
}
public TreeNode(int val){
this.val=val;
}
}
public static void main(String[] args) {
TreeNode t=new TreeNode(10);
TreeNode t1=new TreeNode(1);
TreeNode t2=new TreeNode(9);
TreeNode t3=new TreeNode(4);
TreeNode t4=new TreeNode(6);
TreeNode t5=new TreeNode(12);
TreeNode t6=new TreeNode(11);
TreeNode t7=new TreeNode(2);
insertTreeNode(t,t1);
insertTreeNode(t,t2);
insertTreeNode(t,t3);
insertTreeNode(t,t4);
insertTreeNode(t,t5);
insertTreeNode(t,t6);
insertTreeNode(t,t7);
PrintBinaryTreeBacUnrecur1(t);
// PrintBinaryTreeMidUnrecur(t);
// System.out.println(t.left.right.right.right.val);
// System.out.println(t.right.right.val);
// System.out.println("先序遍历");
// selectXDf(t);
//System.out.println("中序遍历");
//selectZDf(t);
// System.out.println("后序遍历");
// selectHDf(t);
}
//先序遍历
public static void selectXDf(TreeNode root){
if(root==null){
return;
}
System.out.println(root.val);
selectXDf(root.left);
selectXDf(root.right);
}
//中序遍历
public static void selectZDf(TreeNode root){
if(root==null){
return;
}
selectZDf(root.left);
System.out.println(root.val);
selectZDf(root.right);
}
//后序遍历
public static void selectHDf(TreeNode root){
if(root==null){
return;
}
selectHDf(root.left);
selectHDf(root.right);
System.out.println(root.val);
}
//向树中插入数据
public static TreeNode insertTreeNode(TreeNode root,TreeNode node){
TreeNode t=root;
TreeNode a=root;
while(t!=null){
a=t;
if(node.val>t.val){
t=t.right;
}else{
t=t.left;
}
}
if(a!=null){
if(node.val>a.val){
a.right=node;
}else{
a.left=node;
}
}
return root;
}
/*
* 先序遍历二叉树(非递归)
* 思路:对于任意节点T,访问这个节点并压入栈中,然后访问节点的左子树,
* 遍历完左子树后,取出栈顶的节点T,再先序遍历T的右子树
*/
public static void PrintBinaryTreePreUnrecur(TreeNode root){
Stack<TreeNode> stack =new Stack<>();
TreeNode p=root;
while (!stack.isEmpty()||p!=null){
if(p!=null){
//当前节点不为空。访问并压入栈中。并将当前节点赋值为左儿子
stack.push(p);
System.out.println(p.val);
p=p.left;
}else {
//当前节点为空:
// 1、当p指向的左儿子时,此时栈顶元素必然是它的父节点
// 2、当p指向的右儿子时,此时栈顶元素必然是它的爷爷节点
//取出栈顶元素,赋值为right
p=stack.pop();
p=p.right;
}
}
}
/*
// * 中序遍历二叉树(非递归)
// *
// * 思路:先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,
// * 出栈,访问T->data,再中序遍历T的右子树。
// */
public static void PrintBinaryTreeMidUnrecur(TreeNode root){
Stack<TreeNode> stack =new Stack<>();
TreeNode p=root;
//当前节点不为空。压入栈中。并将当前节点赋值为左儿子
while (!stack.isEmpty()||p!=null){
if(p!=null){
stack.push(p);
p=p.left;
}else {
//当前节点为空:
// 1、当p指向的左儿子时,此时栈顶元素必然是它的父节点
// 2、当p指向的右儿子时,此时栈顶元素必然是它的爷爷节点
//取出并访问栈顶元素,赋值为right
p=stack.pop();
System.out.println(p.val);
p=p.right;
}
}
}
// /*
// * 后序遍历二叉树(非递归)
// *
// */
public static void postOrder(TreeNode biTree)
{//后序遍历非递归实现
int left = 1;//在辅助栈里表示左节点
int right = 2;//在辅助栈里表示右节点
Stack<TreeNode> stack = new Stack<TreeNode>();
Stack<Integer> stack2 = new Stack<Integer>();
//辅助栈,用来判断子节点返回父节点时处于左节点还是右节点。
while(biTree != null || !stack.empty())
{
while(biTree != null)
{//将节点压入栈1,并在栈2将节点标记为左节点
stack.push(biTree);
stack2.push(left);
biTree = biTree.left;
}
while(!stack.empty() && stack2.peek() == right)
{//如果是从右子节点返回父节点,则任务完成,将两个栈的栈顶弹出
stack2.pop();
System.out.println(stack.pop().val);
}
if(!stack.empty() && stack2.peek() == left)
{//如果是从左子节点返回父节点,则将标记改为右子节点
stack2.pop();
stack2.push(right);
biTree = stack.peek().right;
}
}
}
public static void PrintBinaryTreeBacUnrecur(TreeNode root){
}
/*
// * 层次遍历二叉树(非递归)
// */
public static void PrintBinaryTreeBacUnrecur1(TreeNode root){
Queue<TreeNode> queue=new LinkedList<TreeNode>();
queue.add(root);
TreeNode p=root;
while (!queue.isEmpty()) {
p=queue.remove();
System.out.println(p.val);
if(p.left!=null){
queue.add(p.left);
} if(p.right!=null){
queue.add(p.right);
} }
}
}