java实现二叉树的各种遍历

java实现二叉树二叉排序树的创建,二叉树的先序、中序、后序(递归和非递归)、层序遍历

 

package com.lmm.test;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 * @author lmm E-mail:violet_mmhh@163.com
 * @time 时间:2019年4月8日
 * @function 功能:
 */
// 实现二叉排序树
public class BinarySortTree {

	public static void main(String[] args) {
		BinaryTree biTree = new BinaryTree();
		int[] data = { 2, 8, 7, 4, 9, 3, 1, 6, 7, 5 };
		biTree.buildTree(data);
		System.out.println("二叉树的中序遍历:");
		biTree.inOrder();
		System.out.println();
		System.out.println("二叉树非递归的中序遍历:");
		biTree.nonrecursiveinOrder();
		System.out.println();
		System.out.println("二叉树的先序遍历:");
		biTree.preOrder();
		System.out.println();
		System.out.println("二叉树非递归的先序遍历:");
		biTree.nonrecursivepreOrder();
		System.out.println();
		System.out.println("二叉树的后序遍历:");
		biTree.postOrder();
		System.out.println();
		System.out.println("二叉树非递归的后序遍历:");
		biTree.nonrecursivepostOrder();
		System.out.println();
		System.out.println("二叉树的层序遍历:");
		biTree.levelTraversal();
		System.out.println();
		// System.out.println("带行号的二叉树层序遍历:");
		// biTree.levelTraversalWithLineNo();
		// System.out.println();
	}

}

class Node {
	public int data;
	public Node left;
	public Node right;

	public Node(int val) {
		this.data = val;
		this.left = null;
		this.right = null;
	}
}

class BinaryTree {
	public Node root;

	public BinaryTree() {
		root = null;
	}

	// 将data插入到二叉排序树中
	public void insert(int data) {
		Node newNode = new Node(data);
		if (root == null) {
			root = newNode;
		} else {
			Node current = root;
			Node parent;
			while (true) {// 寻找插入的位置
				parent = current;
				if (data < current.data) {
					current = current.left;
					if (current == null) {
						parent.left = newNode;
						return;
					}
				} else {
					current = current.right;
					if (current == null) {
						parent.right = newNode;
						return;
					}
				}
			}
		}
	}

	// 将数值输入构建二叉树
	public void buildTree(int[] data) {
		for (int i = 0; i < data.length; i++) {
			insert(data[i]);
		}
	}

	// 中序遍历方法递归实现
	public void inOrder(Node localRoot) {
		if (localRoot != null) {
			inOrder(localRoot.left);
			System.out.print(localRoot.data + " ");
			inOrder(localRoot.right);
		}
	}

	public void inOrder() {
		this.inOrder(this.root);
	}

	// 非递归实现中序遍历
	public void nonrecursiveinOrder(Node localRoot) {
		Stack<Node> st = new Stack<>();
		Node node = localRoot;
		while (node != null || !st.empty()) {
			while (node != null) {
				st.push(node);
				node = node.left;
			}
			if (!st.empty()) {
				node = st.pop();
				System.out.print(node.data + " ");
				node = node.right;
			}
		}
	}

	public void nonrecursiveinOrder() {
		this.nonrecursiveinOrder(this.root);
	}

	// 先序遍历方法递归实现
	public void preOrder(Node localRoot) {
		if (localRoot != null) {
			System.out.print(localRoot.data + " ");
			preOrder(localRoot.left);
			preOrder(localRoot.right);
		}
	}

	public void preOrder() {
		this.preOrder(this.root);
	}

	// 非递归实现先序遍历
	public void nonrecursivepreOrder(Node localRoot) {
		Stack<Node> st = new Stack<>();
		Node node = localRoot;
		while (node != null || !st.empty()) {
			while (node != null) {
				System.out.print(node.data + " ");
				st.push(node);
				node = node.left;
			}
			node = st.pop();
			node = node.right;
		}
	}

	public void nonrecursivepreOrder() {
		this.nonrecursivepreOrder(this.root);
	}

	// 后序遍历方法递归实现
	public void postOrder(Node localRoot) {
		if (localRoot != null) {
			postOrder(localRoot.left);
			postOrder(localRoot.right);
			System.out.print(localRoot.data + " ");
		}
	}

	public void postOrder() {
		this.postOrder(this.root);
	}

	// 非递归实现后序遍历
	public void nonrecursivepostOrder(Node localRoot) {
		Stack<Node> st = new Stack<>();
		Node node = localRoot;
		Node node2 = localRoot;
		while (node != null) {
			// 左子树入栈
			while (node.left != null) {
				st.push(node);
				node = node.left;
			}
			// 当前结点无右子树或右子树已经输出
			while (node.right == null || node.right == node2) {
				System.out.print(node.data + " ");
				node2 = node;// 纪录上一个已输出结点
				if (st.empty())
					return;
				node = st.pop();
			}
			// 处理右子树
			st.push(node);
			node = node.right;
		}
	}

	public void nonrecursivepostOrder() {
		this.nonrecursivepostOrder(this.root);
	}

	/**
	 * 层序遍历二叉树(每一行从左到右,整体上从上到下) 主要思路:利用队列先进先出的性质保存顺序
	 * 
	 * @param root
	 *            要遍历的二叉树的根节点
	 */
	public void levelTraversal(Node root) {
		Queue<Node> q = new LinkedList<>();
		q.add(root);
		while (!q.isEmpty()) {
			Node temp = q.poll();
			if (temp != null) {
				System.out.print(temp.data + " ");
				if (temp.left != null)
					q.add(temp.left);
				if (temp.right != null)
					q.add(temp.right);
			}
		}
	}

	public void levelTraversal() {
		this.levelTraversal(this.root);
	}

	/**
	 * 层序遍历二叉树(每一行从左到右,整体上从上到下),并附带行号 主要思路:利用队列先进先出的性质保存顺序来层序遍历二叉树。
	 * 使用curLineLast与nextLineLast两个节点标志来标识遍历过程中当前行结尾节点与下一行结尾节点,
	 * 再使用一个lineNo整形量来记录当前行号(初始设为1),并在curLineLast节点更替时,更新lineNo的值并按格式打印即可。
	 * 注:nextLineLast始终指向最新遍历到的节点
	 * 
	 * @param root
	 *            要遍历的二叉树的根节点
	 */
	public void levelTraversalWithLineNo(Node root) {
		// 加入断言,保证root不为null
		assert root != null;
		// curLineLast : 当前行结尾节点
		// nextLineLast : 下一行结尾节点
		// 刚开始时,curLineLast与nextLineLast均指向根节点
		Node curLineLast = root, nextLineLast = root;
		// 设根节点所在的行为第1行
		int lineNo = 1;
		System.out.print(lineNo + " : ");
		Queue<Node> q = new LinkedList<>();
		q.add(root);
		while (!q.isEmpty()) {
			Node temp = q.poll();
			// 只有当前节点的子节点不为空时,nextLineLast才需要更改指向的目标
			if (temp.left != null) {
				q.add(temp.left);
				nextLineLast = temp.left;
			}
			if (temp.right != null) {
				q.add(temp.right);
				nextLineLast = temp.right;
			}
			System.out.print(temp.data + "  ");
			// 当出栈节点为当前行尾节点时,说明该换行了
			if (curLineLast == temp) {
				// 将当前行尾节点指向下一行尾节点
				curLineLast = nextLineLast;
				System.out.print(System.lineSeparator() + ++lineNo + " : ");
			}
		}
	}

	public void levelTraversalWithLineNo() {
		this.levelTraversalWithLineNo(this.root);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现二叉树的层次遍历,可以使用递归的方式来完成。首先,我们可以定义一个辅助函数levelOrderHelper,该函数接收一个二叉树的根节点,一个存储层次遍历结果的列表和一个表示当前层次的参数level。在levelOrderHelper函数中,我们首先判断当前节点是否为空,如果为空则直接返回。接下来,我们判断当前层次是否已经在列表中创建了对应的列表,如果没有,则创建一个新的列表。然后,将当前节点的值添加到对应层次的列表中。接着,我们递归调用levelOrderHelper函数遍历当前节点的左子树,并将层次参数level加1。再递归调用levelOrderHelper函数遍历当前节点的右子树,并将层次参数level加1。最后,我们可以定义一个levelOrder函数,该函数接收二叉树的根节点作为参数,并在其中创建一个空的结果列表。然后,我们调用levelOrderHelper函数对二叉树进行层次遍历,并将结果存储到结果列表中。最后,返回结果列表作为层次遍历的结果。 ```java //二叉树的层次遍历 public List<List<String>> levelOrder(Tree root){ List<List<String>> list = new ArrayList<>(); levelOrderHelper(root, list, 0); return list; } //层级遍历辅助 public void levelOrderHelper(Tree root, List<List<String>> list, int level) { if(root == null) { return; } if(level >= list.size()) { list.add(new ArrayList<>()); } list.get(level).add(root.val); levelOrderHelper(root.left, list, level + 1); levelOrderHelper(root.right, list, level + 1); } ``` 以上代码是一个简单的Java实现二叉树层次遍历的示例,其中Tree表示二叉树的节点,root表示二叉树的根节点。函数levelOrder接收二叉树的根节点作为参数,并返回一个列表,列表中包含了二叉树的层次遍历结果。函数levelOrderHelper是一个辅助函数,用于递归地进行二叉树的层次遍历,将每个层次的元素分别存储起来。最后,我们可以调用levelOrder函数进行二叉树的层次遍历。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Java:实现二叉树的层次遍历](https://blog.csdn.net/qq_45000317/article/details/123143184)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Java实现二叉树遍历](https://blog.csdn.net/m0_37911706/article/details/125268444)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值