二叉树、二叉排序树及相关遍历java实现

package cn.csu.trees;

public class BinaryTreeNode {
	/*
	 * 一个二叉树包括 数据、左右孩子  三部分
	 */
	private int data;
	private BinaryTreeNode leftChild;
	private BinaryTreeNode rightChild;
	
	public BinaryTreeNode(int data, BinaryTreeNode leftChild,
			BinaryTreeNode rightChild) {
		super();
		this.data = data;
		this.leftChild = leftChild;
		this.rightChild = rightChild;
	}
	
	public int getData() {
		return data;
	}
	public void setData(int data) {
		this.data = data;
	}

	public BinaryTreeNode getLeftChild() {
		return leftChild;
	}
	public void setLeftChild(BinaryTreeNode leftChild) {
		this.leftChild = leftChild;
	}

	public BinaryTreeNode getRightChild() {
		return rightChild;
	}
	public void setRightChild(BinaryTreeNode rightChild) {
		this.rightChild = rightChild;
	}
}
package cn.csu.trees;


public class BinaryTree {
	/*
	 * 创建一个二叉树很简单,只要有一个二叉根节点,然后提供设置根节点的方法即可
	 */
	private BinaryTreeNode root;//根节点
	
	public BinaryTree(){
	}
	public BinaryTree(BinaryTreeNode root) {
		super();
		this.root = root;
	}

	public BinaryTreeNode getRoot() {
		return root;
	}
	public void setRoot(BinaryTreeNode root) {
		this.root = root;
	}
	/**
	 * 添加左子树
	 * @param child
	 */
	public void insertAsLeftChild(BinaryTreeNode child){
		checkTreeEmpty();
		root.setLeftChild(child);
	}
	/**
	 * 添加右子树
	 * @param child
	 */
	public void insertAsRightChild(BinaryTreeNode child){
		checkTreeEmpty();
		root.setRightChild(child);
	}
	/**
	 * 检查二叉树是否已经创建
	 * 在每次插入节点前都会检查二叉树是否为空,如果为空就抛出异常
	 */
	private void checkTreeEmpty() {
		if(root == null){
			throw new IllegalStateException("Can't insert to a null tree! Did you forget set value fot root?");
		}
	}
	/**
	 * 删除节点元素,只要把对应的节点设置为空(null)即可
	 * 但是为了避免浪费不必要的内存,方便GC及时回收,我们还需要删除该节点对应的左右子树
	 * @param node
	 */
	public void deleteNode(BinaryTreeNode node){
		checkTreeEmpty();
		if(node == null){//递归出口
			return;
		}
		deleteNode(node.getLeftChild());
		deleteNode(node.getRightChild());
		node = null;
	}
	/**
	 * 清空二叉树
	 * 二叉树的清空其实就是删除节点元素的一种特殊情况,即删除根节点元素
	 */
	public void clearTree(){
		if(root!=null){
			deleteNode(root);
		}
	}
	/**
	 * 获得指定节点的高度
	 * @param node
	 * @return
	 */
	public int getHight(BinaryTreeNode node){
		if(node == null){//递归出口
			return 0;
		}
		int leftChildHight = getHight(node.getLeftChild());//当前节点的左子树高度
		int rightChildHight = getHight(node.getRightChild());//当前节点的右子树高度
		int max = (leftChildHight>rightChildHight)?leftChildHight:rightChildHight;
		return max + 1;//加上自己本身
	}
	/**
	 * 获取树的高度
	 * 可以看成获取指定节点高度的特殊情况 根节点
	 * @return
	 */
	public int getTreeHight(){
		return getHight(root);
	}
	/**
	 * 获取指定节点对应子树的节点数
	 * @param node
	 * @return
	 */
	public int getSize(BinaryTreeNode node){
		if(node == null){
			return 0;
		}
		int leftSize = getSize(node.getLeftChild());//获取左子树节点数
		int rightSize = getSize(node.getRightChild());//获取右子树节点数
		return leftSize + rightSize + 1;//返回当前节点对应子树节点总数
	}
	/**
	 * 获取二叉树的节点数
	 * 可以看成获取指定节点对应子树的节点数特殊情况 根节点 
	 * @return
	 */
	public int getTreeSize(){
		return getSize(root);
	}
	/**
	 * 返回指定节点的直接父节点
	 * @param node
	 * @return
	 */
	public BinaryTreeNode getParent(BinaryTreeNode node){
		if(node == root || root == null){//如果这个节点就是根节点或者这棵树为空树返回null
			return null;
		}
		return getParent(root,node);//如果不是根节点并且不为空树,这时就要从根节点开始递归查找父节点
	}
	/**
	 * 递归对比节点的孩子节点与指定节点是否一致
	 * @param subTreeNode 子二叉树根节点
	 * @param node 指定节点
	 * @return
	 */
	private BinaryTreeNode getParent(BinaryTreeNode subTreeNode, BinaryTreeNode node) {
		if(subTreeNode == null){//如果子树为空,则没有父节点  递归出口 1
			return null;
		}
		if(subTreeNode.getLeftChild() == node || subTreeNode.getRightChild() == node){
			return subTreeNode;//如果左孩子或者右孩子为指定节点则当前判断节点即为父节点  递归出口 2
		}
		//否则遍历左右子树
		BinaryTreeNode parent = getParent(subTreeNode.getLeftChild(), node);//查找左子树
		if(parent != null){
			return parent;
		}
		return getParent(subTreeNode.getRightChild(), node);//查找右子树
	}
	/**
	 * 二叉树先序遍历
	 * 根 左 右
	 * @param node
	 */
	public void iteratorFirstOrder(BinaryTreeNode node){
		if(node == null){
			return;
		}
		operate(node);//操作节点
		iteratorFirstOrder(node.getLeftChild());
		iteratorFirstOrder(node.getRightChild());
	}
	public void iteratorFirstOrder(){
		this.iteratorFirstOrder(this.root);
	}
	/**
	 * 模拟节点操作
	 * @param node
	 */
	private void operate(BinaryTreeNode node) {
		if(node == null){
			return;
		}
		System.out.println(node.getData());
	}
	/**
	 * 二叉树中序遍历
	 * 左 根 右
	 * @param node
	 */
	public void iteratorMediumOrder(BinaryTreeNode node){
		if(node == null){
			return;
		}
		iteratorMediumOrder(node.getLeftChild());
		operate(node);
		iteratorMediumOrder(node.getRightChild());
	}
	public void iteratorMediumOrder(){
		this.iteratorMediumOrder(this.root);
	}
	/**
	 * 二叉树后序遍历
	 * 左 右 根
	 * @param node
	 */
	public void iteratorLastOrder(BinaryTreeNode node){
		if(node == null){
			return;
		}
		iteratorLastOrder(node.getLeftChild());
		iteratorLastOrder(node.getRightChild());
		operate(node);
	}
	public void iteratorLastOrder(){
		this.iteratorLastOrder(this.root);
	}
	/**
	 * 建立二叉排序树
	 * @param data
	 */
	public void insert(int data){
		BinaryTreeNode node = new BinaryTreeNode(data, null, null);//待插入排序树的节点
		if(root == null){
			root = node;
		}else{
			BinaryTreeNode track = root;//跟踪插入位置
			BinaryTreeNode trackParent;
			while(true){
				trackParent = track;
				if(track.getData() > data){//左查找并插入
					track = track.getLeftChild();
					if(track == null){
						trackParent.setLeftChild(node);
						return;
					}
				}else if(track.getData() < data){//右查找并插入
					track = track.getRightChild();
					if(track == null){
						trackParent.setRightChild(node);
						return;
					}
				}
			}
		}
	}
	
}
package cn.csu.trees;
public class BinaryTreeUtils {
	public static void main(String[] args) {
		int[] firstOrder = new int[]{1,2,4,7,3,5,8,9,6};//1 2 4 7 3 5 8 9 6
		int[] mediumOrder = new int[]{4,7,2,1,8,5,9,3,6};//4 7 2 1 8 5 9 3 6
		BinaryTree binaryTree = new BinaryTree();
//		binaryTree.iteratorLastOrder(crateBinaryTree(firstOrder,mediumOrder,firstOrder.length));
		for (int i = 0; i < mediumOrder.length; i++) {
			binaryTree.insert(mediumOrder[i]);
		}
		binaryTree.iteratorMediumOrder();
	}
	/**
	 * 
	 * @param firstOrder 前序遍历数组
	 * @param mediumOrder 中序遍历数组
	 * @param length 数组长度
	 * @return 根节点
	 */
	private static BinaryTreeNode crateBinaryTree(int[] firstOrder,
			int[] mediumOrder, int length) {
		if(firstOrder == null || mediumOrder == null || firstOrder.length <= 0){
			return null;                                                                            
		}
		return createCore(firstOrder,0,firstOrder.length-1,mediumOrder,0,mediumOrder.length-1);
	}

	private static BinaryTreeNode createCore(int[] firstOrder, int firstStart, int firstEnd,
			int[] mediumOrder, int mediumSrart,int mediumEnd) {
		int rootValue = firstOrder[firstStart];
		BinaryTreeNode root = new BinaryTreeNode(rootValue, null, null);
		if(firstStart == firstEnd){//递归出口 
			if(mediumSrart == mediumEnd && firstOrder[firstStart] == mediumOrder[mediumSrart]){
				return root;
			}else{
				throw new RuntimeException("Order Error!Can't crare Tree on your data!");
			}
		}
		int rootIndex = mediumSrart;
		while(rootIndex <= mediumEnd && mediumOrder[rootIndex] != rootValue){
			++rootIndex;//在中序遍历中找到根节点的索引
		}
		if(rootIndex == mediumEnd && mediumOrder[rootIndex] != rootValue){//异常处理
			throw new RuntimeException("Can't find rootTndex!");
		}
		int leftLength = rootIndex - mediumSrart;//左子树数组长度
		int leftFirstOrderEndIndex = firstStart + leftLength;//左子树前序遍历下边界
		if(leftLength > 0){
			//构建左子树
			root.setLeftChild(createCore(firstOrder, firstStart+1, leftFirstOrderEndIndex, 
					mediumOrder, mediumSrart, rootIndex-1));
		}
		if(leftLength < firstEnd-firstStart){
			//右子树有元素,构建右子树
			root.setRightChild(createCore(firstOrder, leftFirstOrderEndIndex+1, firstEnd, mediumOrder, rootIndex+1, mediumEnd));
		}
		return root;
	}
	
	
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值