Java实现二叉树的中序遍历

标题: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());
	
	}
	
}



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值