利用Java实现二叉树的插入和遍历

本文详细介绍了二叉树的添加、遍历及深度计算方法,包括先序、中序、后序遍历的具体实现,以及如何计算二叉树的深度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.mldn.BinaryTree;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * 时间:2019年7月25日 项目名称:MyProject02 二叉树的添加和遍历
 * 
 * @author Administrator
 */

class Tree {
	private Node root; // 根节点
	private ArrayList<Node> result = new ArrayList<Node>(); // 存放结果
	private int floor = 1;
	private ArrayList<Integer> floors = new ArrayList<Integer>();  //存放楼层
	private int temp = -1 ;
	/**
	 * 插入函数用到的方法
	 * 
	 * @param num
	 */
	public void add(int num) {
		Node newNode = new Node();
		newNode.setNum(num); // 将数字放到节点里面
		if (root == null) { // 如果根节点为空 将这个节点设置为根节点
			this.root = newNode;
		} else { // 有根节点
			insert(newNode, root); // 用向树里面添加
		}
	}

	/**
	 * 将节点插入二叉树
	 * 
	 * @param num        要插入的节点
	 * @param parentNode 父节点
	 * @return boolean 如果小就让左节点 当父节点 如果大就让右节点 当父节点 递归 插入成功true 失败false
	 */
	private boolean insert(Node src, Node parentNode) {
		if (src.getNum() < parentNode.getNum()) { // 如果小于 往左插
			if (parentNode.getLeftChild() == null) { // 如果等于空
				parentNode.setLeftChild(src); // 插入
				return true;
			} else { // 说明有左节点
				Node parent = parentNode.getLeftChild(); // 子节点为父节点
				insert(src, parent); // 递归
			}
		} else { // 大于等于 往右边插
			if (parentNode.getRightChild() == null) { // 如果等于空
				parentNode.setRightChild(src); // 插入
				return true;
			} else { // 说明有左节点
				Node parent = parentNode.getRightChild(); // 子节点为父节点
				insert(src, parent); // 递归
			}
		}

		return false;
	}

	/**
	 * 实现二叉树的先序遍历 根 左 右
	 * 
	 * @return
	 */
	public ArrayList<Integer> nlr() {
		result.clear(); // 使用前先清除存放结果的容器
		ArrayList<Node> nodes = new ArrayList<Node>();
		nodes = NLR(root);
		// 取出节点 剥皮取出数据存放到容器内
		ArrayList<Integer> arr = new ArrayList<Integer>();
		for (Node node : nodes) {
			arr.add(node.getNum());
		}

		return arr;

	}

	/**
	 * 先序遍历的实现方法 根 左 右
	 * 
	 * @param nodes
	 * @return
	 */
	private ArrayList<Node> NLR(Node root) {
		if (root.getLeftChild() != null) { // 如果有左节点
			Node parent = root.getLeftChild(); // 左当根
			result.add(root); // 先把自己(根)添加进去,再左右
			NLR(parent);
		}
		if (root.getRightChild() != null) { // 如果有右节点
			Node parent = root.getRightChild(); // 右当根
			if (root.getLeftChild() == null) // 因为有左节点的 都已经把自己添加过了,所以把没有左节点的在添加进去
				result.add(root); // 先把自己(根)添加进去,再左右
			NLR(parent);
		}
		if (root.getLeftChild() == null && root.getRightChild() == null) {
			result.add(root); // 如果没有子节点,把自己添加进去
		}

		return result;
	}

	/**
	 * 二叉树的中序遍历
	 * 
	 * @return
	 */
	public ArrayList<Integer> lnr() {
		result.clear(); // 清空容器
		// 扒皮
		ArrayList<Integer> arr = new ArrayList<Integer>();
		for (Node node : LNR(root)) {
			arr.add(node.getNum());
		}
		return arr;
	}

	/**
	 * 实现二叉树的中序遍历 不管怎么样 都是先 左 根 右 有重复值
	 */
	private ArrayList<Node> LNR(Node root) {
		if (root.getLeftChild() != null) { // 如果左边有
			Node parent = root.getLeftChild(); // 左子节点当父节点往下找
			LNR(parent);
			result.add(root); // 当儿子们都找完后自己在加进去
		}
		// 如果左右都有
		if (root.getLeftChild() != null && (root.getRightChild() != null)) {
			result.remove(root); // 先把自己删了,防止放右前 的放中导致重复
		}
		if (root.getRightChild() != null) { // 如果右边有
			Node parent = root.getRightChild(); // 右边有,右节点当父节点,但是还是得先判断左子树
			result.add(root); // 按照顺序 左中右 先把自己(中)添加里面
			LNR(parent); // 判断
		}
		if (root.getLeftChild() == null && (root.getRightChild() == null)) {
			result.add(root); // 如果左右都没有就把自己加里面
		}
		return result;
	}

	/**
	 * 二叉树的后序遍历 左右根
	 * 
	 * @return
	 */
	public ArrayList<Integer> lrn() {
		result.clear();
		ArrayList<Integer> arr = new ArrayList<Integer>();
		for (Node node : LRN(root)) {
			arr.add(node.getNum());
		}
		return arr;

	}

	/**
	 * 实现后序遍历 左右根
	 */
	private ArrayList<Node> LRN(Node root) {
		if (root.getLeftChild() != null) { // 如果有左
			Node parent = root.getLeftChild(); // 左当父
			LRN(parent); // 递归
			result.add(root); // 回来在把自己填进去
		}
		if (root.getLeftChild() != null && root.getRightChild() != null) { // 如果两边都有
			result.remove(root); // 先把自己删了
		}
		if (root.getRightChild() != null) { // 如果有右
			Node parent = root.getRightChild(); // 右当父
			LRN(parent);
			result.add(root); // 右边把自己填进去
		}
		if (root.getLeftChild() == null && root.getRightChild() == null) {// 如果都没有
			result.add(root); // 自己填进去
		}
		return result;

	}

	/**
	 * 返回二叉树的层数
	 * 最大数即为深度
	 */
	public int getFloor() {
		ArrayList<Integer> maxs = treeDeep(root);
		int max =maxs.get(0);
		for (int i = 0; i < maxs.size()-1; i++) {
			if(maxs.get(i) < maxs.get(i+1)) {
				max = maxs.get(i+1);
			}
		}
		return max;
	}

	/**
	 * 遍历所有分支  存放到floors容器中
	 * @return
	 */
	private ArrayList<Integer> treeDeep(Node node) {
		//如果是双叶子节点
		if(node.getLeftChild() != null && node.getRightChild() != null) {
			floor++;
			temp = floor;
			treeDeep(node.getLeftChild());
			treeDeep(node.getRightChild());
		}
		//如果只有左
		if(node.getLeftChild()!=null && node.getRightChild()==null) {
			floor++;
			treeDeep(node.getLeftChild());
		}
		//如果只有右
		if(node.getLeftChild()==null && node.getRightChild()!=null) {
			floor++;
			treeDeep(node.getRightChild());
		}
		//如果都没有
		if(node.getLeftChild()==null &&node.getRightChild()==null) {
			floors.add(floor);
			floor = temp;
			temp = -1;
		}
		return floors;
	}
}

class Node {
	private int num;
	private Node leftChild;
	private Node rightChild;

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public Node getLeftChild() {
		return leftChild;
	}

	public void setLeftChild(Node leftChild) {
		this.leftChild = leftChild;
	}

	public Node getRightChild() {
		return rightChild;
	}

	public void setRightChild(Node rightChild) {
		this.rightChild = rightChild;
	}
}

public class BinaryTree {
	public static void main(String[] args) {
		Tree t1 = new Tree();
		t1.add(50);
		t1.add(20);
		t1.add(70);
		t1.add(15);
		t1.add(60);
		t1.add(80);
		t1.add(62);
		System.out.println("先序遍历---"+t1.nlr().toString()); // 先序遍历
		System.out.println("中序遍历---"+t1.lnr().toString()); // 中序遍历
		System.out.println("后序遍历---"+t1.lrn().toString()); // 后序遍历
		System.out.println("深度---"+t1.getFloor());
	}
}

结果:
先序遍历—[50, 20, 15, 70, 60, 62, 80]
中序遍历—[15, 20, 50, 60, 62, 70, 80]
后序遍历—[15, 20, 62, 60, 80, 70, 50]
深度—4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值