二叉树的先序,中序,后序遍历(递归版与非递归版本)

先序遍历:先遍历当前节点,再遍历当前节点的左孩子,在遍历当前节点的有孩子
把打印的时机放到第几次遍历这个节点,对应不同的遍历
当第一次来到这个节点的时候,对应先序遍历
当第二次来到这个节点的时候,对应中序遍历
当第三次来到这个节点的时候,对应后续遍历
递归版

/先序遍历
public static void preOrderRecur(Node head) {
   if (head == null) {
      return;
   }
   System.out.print(head.value + " ");
   preOrderRecur(head.left);
   preOrderRecur(head.right);
}
//中序遍历
public static void inOrderRecur(Node head) {
   if (head == null) {
      return;
   }
   inOrderRecur(head.left);
   System.out.print(head.value + " ");
   inOrderRecur(head.right);
}
//后续遍历
public static void posOrderRecur(Node head) {
   if (head == null) {

      return;
   }
   posOrderRecur(head.left);
   posOrderRecur(head.right);
   System.out.print(head.value + " ");
}

非递归版
先序遍历:首先创建一个栈,用于存储节点,先将根节点存储到栈中,判断栈是否为空,在将栈中元素弹出,赋值给树,并打印当前节点,并判断当前节点的有子树是否为空,若不为空,则将当前节点的左子树压入栈中,再判断当前节点的左子树是否为空,若不为空,将当前节点的左子树压入栈中。

public static void preOrderUnRecur(Node head) {
   System.out.print("pre-order: ");
   if (head != null) {
      Stack<Node> stack = new Stack<Node>();
      stack.push(head);
      while (!stack.isEmpty()) {
         head = stack.pop();
         System.out.print(head.value + " ");
         if (head.right != null) {
            stack.push(head.right);
         }
         if (head.left != null) {
            stack.push(head.left);
         }
      }
   }
   System.out.println();
}

中序遍历:创建一个栈,判断栈或树节点是否为空,再判断当前节是否为空,若不为空,将当前节点压如栈中,当前节点指向当前节点的左子树,如果当前节点为空,栈弹出节点,打印栈弹出的节点,当前节点指向当前节点的右子树。

public static void inOrderUnRecur(Node head) {
   System.out.print("in-order: ");
   if (head != null) {
      Stack<Node> stack = new Stack<Node>();
      while (!stack.isEmpty() || head != null) {
         if (head != null) {
            stack.push(head);
            head = head.left;
         } else {
            head = stack.pop();
            System.out.print(head.value + " ");
            head = head.right;
         }
      }
   }
   System.out.println();
}

后续遍历:由于后续遍历是第三次来到节点,但是栈只能两次访问节点,因此另辟蹊径
首先根据先序遍历,很容易实现的是 当前节点,右子树,左子树的遍历顺序,因此新建一个栈,保存另一个栈中弹出的结点,访问结束后进行打印,因此可以得到先左子树,再右子树,最后根节点的遍历顺序。

public static void posOrderUnRecur1(Node head) {
   System.out.print("pos-order: ");
   if (head != null) {
      Stack<Node> s1 = new Stack<Node>();
      Stack<Node> s2 = new Stack<Node>();
      s1.push(head);
      while (!s1.isEmpty()) {
         head = s1.pop();
         s2.push(head);
         if (head.left != null) {
            s1.push(head.left);
         }
         if (head.right != null) {
            s1.push(head.right);
         }
      }
      while (!s2.isEmpty()) {
         System.out.print(s2.pop().value + " ");
      }
   }
   System.out.println();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值