二叉树的结构和遍历

二叉树

二叉树节点结构

class Node<V>{
V value;
Node left;
Node right;
}

遍历二叉树

用递归和非递归两种方式实现二叉树的先序、 中序、 后序遍历

递归序

先序遍历:对每一棵子树都先打印头,再打印左右。第一次来到的时候打印,第二次第三次来到都不打印。

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 + " ");
}
非递归序

先序遍历:

  1. 准备一个栈,把头节点先压入栈中。从栈中弹出一个节点cur
  2. 打印
  3. 先压右再压左(如果有)
  4. 循环前面步骤
public static void preOrderUnRecur(Node head) {
   System.out.print("pre-order: ");
   if (head != null) {
      Stack<Node> stack = new Stack<Node>();
      stack.add(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();
}

中序遍历:

先头,先左,先右

  1. 准备一个栈,对于每棵子树,将整棵树的左边界节点都进栈
  2. 依次弹的过程中打印
  3. 在这个过程中,对弹出节点的右树进栈,重复这行为
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;   //移动到右孩子上,继续走逻辑分支1
         }
      }
   }
   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();
}

打印

如何直观的打印一颗二叉树?

打印一个可视化的树,代码略

宽度优先遍历

如何完成二叉树的宽度优先遍历(常见题目: 求一棵二叉树的宽度) ?

深度优先遍历,就是先序遍历。

宽度遍历用队列,头节点先进,然后弹出,然后左右进队列

public static void w(Node head) {
   if (head == null) {
      return;
   }
   Queue<Node> queue = new LinkedList<>();
   queue.add(head);
   while (!queue.isEmpty()) {
      Node cur = queue.poll();
      System.out.println(cur.value);
      if (cur.left != null){
         queue.add(cur.left);
      }
      if (cur.right != null){
         queue.add(cur.right);
      }
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写代码的信哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值