Java实现二叉树的中序遍历

it2026-06-17  9

标题:Java实现二叉树的中序遍历

1)递归:

public void midorder(Node p) { if(p == null) { return ; }else { this.midorder(p.left); System.out.print(p.val + " "); this.midorder(p.right); } }

2)或许你会使用这样子的非递归 【在while循环中,直接while循环,这样不够有迭代的思想,同时有时候的问题需要逐步的走循环】

public void midorder02(Node p) { Deque<Node> s = new LinkedList<>(); if(p == null) { return ; } s.push(p); while(!s.isEmpty()) { while(s.peek().left != null) { Node node = s.peek().left; s.push(node); } Node node = s.peek().right; System.out.print(s.pop().val + " "); while(!s.isEmpty() && node == null) { node = s.peek().right; System.out.print(s.pop().val + " "); } if(node != null) { s.push(node); } } }

3)推荐这种

public List<Integer> inOrder06(Node node) { LinkedList<Integer> list = new LinkedList<Integer>(); if(node == null) { return list; } Node p = node; // System.out.print(p.val + " "); // list.add(p.val); while(p != null) { if(p.left == null) { System.out.print(p.val + " "); list.add(p.val); p = p.right; }else { //使用的是if,而不是while,【逐步迭代】 Node p1 = p.left; while(p1.right != null && p1.right != p) { //先写的是p1.right != null, != p是后面补上的 p1 = p1.right; } if(p1.right == null) { //将节点连起来 p1.right = p; p = p.left; }else { //说明已经有了“环路” System.out.print(p.val + " "); list.add(p.val); p = p.right; } } } return list; }

4)使用Morris

public List<Integer> inOrder09(Node node){ LinkedList<Integer> list = new LinkedList<Integer>(); if(node == null) { return list; } Node p = node; while(p != null) { if(p.left != null) { //找到最右边的节点 Node temp = p.left; while(temp.right != null && temp.right != p) { temp = temp.right; } if(temp.right == null) {//连接成环 temp.right = p; // System.out.print(p.val + " "); // list.add(p.val); p = p.left; }else { //本来就是环 System.out.print(p.val + " "); list.add(p.val); p = p.right; temp.right = null;//使得可以还原morris } }else { System.out.print(p.val + " "); list.add(p.val); p = p.right; } } return list; }

完整示例:

package com.hhh.aa.basicTree02; import java.util.Deque; import java.util.LinkedList; import java.util.List; import java.util.Queue; import org.junit.Test; /** * 我的二叉树 【中序遍历】 * @author dell * */ public class TestMyTreeB021 { /** * 测试遍历二叉树的中序遍历【先输出节点的值】 * @param p */ public void midorder(Node p) { if(p == null) { return ; }else { this.midorder(p.left); System.out.print(p.val + " "); this.midorder(p.right); } } /** * 执行用时:10 ms, 在所有 Java 提交中击败了46.21% 的用户 内存消耗:36.7 MB, 在所有 Java 提交中击败了97.69% 的用户 执行用时:1 ms, 在所有 Java 提交中击败了46.21% 的用户 内存消耗:36.7 MB, 在所有 Java 提交中击败了96.71% 的用户 * @param p */ public void midorder02(Node p) { Deque<Node> s = new LinkedList<>(); if(p == null) { return ; } s.push(p); while(!s.isEmpty()) { while(s.peek().left != null) { Node node = s.peek().left; s.push(node); } Node node = s.peek().right; System.out.print(s.pop().val + " "); while(!s.isEmpty() && node == null) { node = s.peek().right; System.out.print(s.pop().val + " "); } if(node != null) { s.push(node); } } } /** * lc简洁 * * 执行用时:10 ms, 在所有 Java 提交中击败了46.06% 的用户 内存消耗:36.7 MB, 在所有 Java 提交中击败了97.19% 的用户 * @param p */ public void midorder03(Node p) { Deque<Node> s = new LinkedList<>(); if(p == null) { return ; } while(p != null || !s.isEmpty()) { while(p != null) { s.push(p); p = p.left; } p = s.pop(); System.out.print(p.val + " "); p = p.right; } } /** * 执行用时:10 ms, 在所有 Java 提交中击败了45.52% 的用户 内存消耗:36.9 MB, 在所有 Java 提交中击败了69.23% 的用户 * @param node * @return */ public List<Integer> inOrder06(Node node) { LinkedList<Integer> list = new LinkedList<Integer>(); if(node == null) { return list; } Node p = node; // System.out.print(p.val + " "); // list.add(p.val); while(p != null) { if(p.left == null) { System.out.print(p.val + " "); list.add(p.val); p = p.right; }else { //使用的是if,而不是while,【逐步迭代】 Node p1 = p.left; while(p1.right != null && p1.right != p) { //先写的是p1.right != null, != p是后面补上的 p1 = p1.right; } if(p1.right == null) { //将节点连起来 p1.right = p; p = p.left; }else { //说明已经有了“环路” System.out.print(p.val + " "); list.add(p.val); p = p.right; } } } return list; } /** * 非递归,book * @param node * @return */ public List<Integer> inOrder07(Node node) { LinkedList<Integer> list = new LinkedList<Integer>(); if(node == null) { return list; } Deque<Node> s = new LinkedList<>(); s.push(node); while(!s.isEmpty()) { Node p = s.peek(); if(p.left != null) { s.push(p.left); }else { //p节点的左边为null System.out.print(p.val + " "); list.add(p.val); //从栈中弹出 s.pop(); //只要右边为null while(p.right == null && !s.isEmpty()) { p = s.pop(); System.out.print(p.val + " "); list.add(p.val); } if(p.right != null) { //先看右边是否为null,而不是看栈,否则导致树的一遍都没有遍历到 s.push(p.right); }else { break; } } } return list; } /** * morris * @param node * @return */ public List<Integer> inOrder09(Node node){ LinkedList<Integer> list = new LinkedList<Integer>(); if(node == null) { return list; } Node p = node; while(p != null) { if(p.left != null) { //找到最右边的节点 Node temp = p.left; while(temp.right != null && temp.right != p) { temp = temp.right; } if(temp.right == null) {//连接成环 temp.right = p; // System.out.print(p.val + " "); // list.add(p.val); p = p.left; }else { //本来就是环 System.out.print(p.val + " "); list.add(p.val); p = p.right; temp.right = null;//使得可以还原morris } }else { System.out.print(p.val + " "); list.add(p.val); p = p.right; } } return list; } /** * 初始化一个tree * 类广度遍历 * @param a * @return */ public Node initTree(Integer[] a) { if(a == null || a.length == 0) { return null; } int t = 0; Node p = new Node(a[t]); //至少有一个元素 Queue<Node> q = new LinkedList<>(); q.offer(p); while(!q.isEmpty()) { Node node = q.poll(); if(t + 1 == a.length) { //先判断数组中是否还有下一个元素 return p; }else { t++; if(a[t] == null) { //若下一个元素为null,则不需要创建新的节点 node.left = null; }else { node.left = new Node(a[t]); q.offer(node.left); } } if(t + 1 == a.length) { return p; }else { t++; if(a[t] != null){ //上面的简写,a[t] == null,不需要再赋值 node.right = new Node(a[t]); q.offer(node.right); } } } return p; } @Test public void test02() { Integer[] a = new Integer[] {1, 2, 3, 4, 5, 9, 10, null, 6, 7, 8, null, null, null, 11}; Node p1 = this.initTree(a); System.out.println("使用递归的中序遍历"); this.midorder(p1); System.out.println(); System.out.println("不使用递归的中序遍历"); this.midorder02(p1); System.out.println(); System.out.println("不使用递归的中序遍历【lc简洁】"); this.midorder03(p1); System.out.println(); // System.out.println("使用morris实现中序遍历"); // List<Integer> list = this.inOrder06(p1); // System.out.println(); // System.out.println("输出list:" + list.toString()); System.out.println("使用非递归遍历"); List<Integer> list = this.inOrder07(p1); System.out.println(); System.out.println("输出list :" + list.toString()); System.out.println("morris"); list = this.inOrder09(p1); System.out.println(); System.out.println("输出list :" + list.toString()); } }
最新回复(0)