Java实现二叉树的遍历

二叉树的遍历分为三种方式:前序遍历,中序遍历,后序遍历,不了解的可参考前一篇文章:二叉树的遍历

先看手绘的一张二叉树的图片:


二叉树的深度的计算方式:length = log2m + 1,此处2为底数,m表示总的节点数,结果取整数;

注意,Java的Math中没有直接提供方法计算log2m,但我们可以做一步转换,转成log2N = logeN / loge2


第m个数的左右孩子节点的下标分别为 层数 * 2 + 1,层数 * 2 + 2;

下面是Java具体的实现,主要是实现了二叉树的构建和三种遍历方式。


先声明一个二叉树节点对象:

package com.zxd.bean;

/**
 * BinaryTreeNode:二叉树对象,包含当前节点值,左孩子结点,右孩子节点
 * 
 * @author zeng.xiangdong 1770534116@qq.com
 * @version V1.0 2014-7-14 下午10:03:57
 */
public class BinaryTreeNode {

	private BinaryTreeNode leftChildNode;
	private BinaryTreeNode rightChildNode;

	private int data;

	public BinaryTreeNode(int data) {
		this.data = data;
	}

	public int getData() {
		return data;
	}

	public void setData(int data) {
		this.data = data;
	}

	public BinaryTreeNode getLeftChildNode() {
		return leftChildNode;
	}

	public void setLeftChildNode(BinaryTreeNode leftChildNode) {
		this.leftChildNode = leftChildNode;
	}

	public BinaryTreeNode getRightChildNode() {
		return rightChildNode;
	}

	public void setRightChildNode(BinaryTreeNode rightChildNode) {
		this.rightChildNode = rightChildNode;
	}

}

再就是二叉树的具体实现:

package com.zxd.link;

import java.util.ArrayList;
import java.util.List;

import com.zxd.bean.BinaryTreeNode;

/**
 * BinaryTreeTraverse:二叉树的遍历
 * 
 * @author zeng.xiangdong 1770534116@qq.com
 * @version V1.0 2014-7-14 下午10:08:32
 */
public class BinaryTreeTraverse {

	/**
	 * create:二叉树的建立
	 * 
	 * @param array 初始值数组
	 * @return List<BinaryTreeNode> 二叉树节点的集合
	 */
	private List<BinaryTreeNode> create(Integer[] array) {
		// 存储二叉树结果集合
		List<BinaryTreeNode> numList = new ArrayList<BinaryTreeNode>();

		for(int num : array) {
			numList.add(new BinaryTreeNode(num));
		}

		// 计算深度:没有直接转化log2N的方法,可转成log2N = logeN/loge2
		// 将深度转成整形
		int size = numList.size();
		int length = (int)(Math.log(size) / Math.log(2)) + 1;

		for(int i = 0; i < length; i++) {
			int leftChildIndex = i * 2 + 1;
			int rightChildIndex = i * 2 + 2;

			// 考虑到不是完全二叉树,如果该节点大于初始化的长度,则返回
			if(leftChildIndex <= size) {
				numList.get(i).setLeftChildNode(numList.get(leftChildIndex));
			} else {
				return numList;
			}
			if(rightChildIndex <= size) {
				numList.get(i).setRightChildNode(numList.get(rightChildIndex));
			} else {
				return numList;
			}
		} // end of for

		BinaryTreeNode lastNode = numList.get(size - 1);
		// 最后一个节点: 最后一个节点应该存放的位置,其父节点下标为 (size - 1)/2;
		// 如果数组长度为复数,则最后一个节点为坐孩子节点,否则为右孩子节点;参考图片
		int lastNodeIndex = (size - 1) / 2;

		if(size % 2 == 0) {
			numList.get(lastNodeIndex).setLeftChildNode(lastNode);
		} else {
			numList.get(lastNodeIndex).setRightChildNode(lastNode);
		}

		return numList;
	}

	/**
	 * dlrTraverse 前序遍历(DLR)
	 * 
	 * @param node 要遍历的节点
	 */
	private void dlrTraverse(BinaryTreeNode node) {
		if(node == null) {
			return;
		}

		System.out.print(node.getData() + " ");
		dlrTraverse(node.getLeftChildNode());
		dlrTraverse(node.getRightChildNode());
	}

	/**
	 * dlrTraverse 中序遍历(LDR)
	 * 
	 * @param node 要遍历的节点
	 */
	private void ldrTraverse(BinaryTreeNode node) {
		if(node == null) {
			return;
		}

		ldrTraverse(node.getLeftChildNode());
		System.out.print(node.getData() + " ");
		ldrTraverse(node.getRightChildNode());
	}

	/**
	 * dlrTraverse 后序遍历(LRD)
	 * 
	 * @param node 要遍历的节点
	 */
	private void lrdTraverse(BinaryTreeNode node) {
		if(node == null) {
			return;
		}

		lrdTraverse(node.getLeftChildNode());
		lrdTraverse(node.getRightChildNode());
		System.out.print(node.getData() + " ");
	}

	// 测试main方法
	public static void main(String[] args) {
		Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

		BinaryTreeTraverse traverse = new BinaryTreeTraverse();
		List<BinaryTreeNode> binaryTreeNodes = traverse.create(array);

		BinaryTreeNode node = binaryTreeNodes.get(0);
		// 前序遍历 DLR
		traverse.dlrTraverse(node);
		System.out.println("-------------------------");

		// 中序遍历 LDR
		traverse.ldrTraverse(node);
		System.out.println("-------------------------");

		// 后序遍历 LRD
		traverse.lrdTraverse(node);
		System.out.println("-------------------------");
	}

}

输出结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值