数据结构---(四)二叉树---Java描述

写在前面:

二叉树(Binary Tree)

特点:每个结点至多有两棵子树(即二叉树中不存在度大于2的结点),且二叉树的子树有左右之分,左子树和右子树不可颠倒。


二叉树的相关操作:

--遍历:(N:Node  L:LeftSubTree  R:RightSubTree)

遍历其实是将二叉树每一个结点按照线性排列的过程。

前序遍历:NLR--根左右

中序遍历:LNR--左根右

后序遍历:LRN--左右根

举例:


比如中序遍历的结果是:(8的左子树)8(8的右子树),而对于8的左子树,以3为根结点,再进行中序遍历=(3的左子树)3(3的右子树),依次类推,那么8的左子树就=1,3,4,6,7。对于8的右子树,以10为根节点进行中序遍历,那么8的右子树=10,13,14,所以最后,中序遍历的结果,就是1,3,4,6,7,8,10,13,14.

接下来,我们来看一下前序遍历,中序遍历,后序遍历的程序实现。

程序实现:

package tree;

import java.util.Stack;

public class BinaryTree {
	private TreeNode root = null;

	public BinaryTree() {
		//设置根节点
		root = new TreeNode(1, "rootNodeA");
	}

	private static class TreeNode {
		private int key;
		private String data = null;
		private TreeNode leftchild;
		private TreeNode rightchild;

		public TreeNode(int key, String data) {
			this.key = key;
			this.data = data;
			this.leftchild = null;
			this.rightchild = null;
		}
		public static TreeNode getParent(TreeNode subTree, TreeNode element) {
			if (subTree == null) {
				return null;
			}
			if (subTree.leftchild == element || subTree.rightchild == element) {
				return subTree;
			}
			TreeNode p;
			if ((p = getParent(subTree.leftchild, element)) != null) {
				return p;
			} else {
				return getParent(subTree.rightchild, element);
			}
		}

	}

	public void createBinTree(TreeNode root) {
		/**
		 * 结构:         A  
		 *           B      C                                                                                                       */       D   E       F
		TreeNode nodeB = new TreeNode(2, "nodeB");
		TreeNode nodeC = new TreeNode(3, "nodeC");
		TreeNode nodeD = new TreeNode(4, "nodeD");
		TreeNode nodeE = new TreeNode(5, "nodeE");
		TreeNode nodeF = new TreeNode(6, "nodeF");
                
		root.leftchild = nodeB;
		root.rightchild = nodeC;
		nodeB.leftchild = nodeD;
		nodeB.rightchild = nodeE;
		nodeC.rightchild = nodeF;

	}

	public TreeNode getRoot() {
		return this.root;
	}

	public boolean isEmpty() {
		return root == null;
	}

	public int height() {
		return height(this.root);
	}
	/**
	 * 树的高度
	 * @param subTree
	 * @return
	 */
	public int height(TreeNode subTree) {
		if (subTree == null) {
			return 0;
		} else {
			int i = height(subTree.leftchild);
			int j = height(subTree.rightchild);
			return (i < j) ? (j + 1) : (i + 1);
		}

	}
	/**
	 * 树中结点的个数
	 * @return
	 */
	public int size() {
		return size(this.root);
	}

	public int size(TreeNode subTree) {
		if (subTree == null) {
			return 0;
		} else {
			return 1 + size(subTree.leftchild) + size(subTree.rightchild);
		}
	}

	public TreeNode Parent(TreeNode element) {
		return (root == null || root == element) ? null : TreeNode.getParent(root, element);
	}

	public TreeNode getLeftChildNode(TreeNode element) {
		return (element != null) ? element.leftchild : null;
	}

	public TreeNode getRightChildNode(TreeNode element) {
		return (element != null) ? element.rightchild : null;
	}

	public static void visted(TreeNode subTree) {
		System.out.println("data: " + subTree.data);
	}
	/**
	 * 前序遍历的递归实现
	 * @param subTree
	 */
	public static void preOrder(TreeNode subTree) {
		if (subTree != null) {
			visted(subTree);
			preOrder(subTree.leftchild);
			preOrder(subTree.rightchild);
		}

	}
	/**
	 * 中序遍历的递归实现
	 * @param subTree
	 */
	public static void inOrder(TreeNode subTree) {
		if (subTree != null) {
			inOrder(subTree.leftchild);
			visted(subTree);
			inOrder(subTree.rightchild);
		}

	}
	/**
	 * 后序遍历的递归实现
	 * @param subTree
	 */
	public static void postOrder(TreeNode subTree) {
		if (subTree != null) {
			postOrder(subTree.leftchild);
			postOrder(subTree.rightchild);
			visted(subTree);

		}

	}
	/**
	 * 前序遍历的非递归实现
	 * @param p
	 */
	public void nonRecPreOrder(TreeNode p) {
		Stack<TreeNode> stack = new Stack<TreeNode>();
		TreeNode node = p;
		while (node != null || stack.size() > 0) {
			while (node != null) {
				visted(node);
				stack.push(node);
				node = node.leftchild;
			}
			if (stack.size() > 0) {
				node = stack.pop();
				node = node.rightchild;
			}
		}
	}
	/**
	 * 中序遍历的非递归实现
	 * @param p
	 */
	public void nonRecInOrder(TreeNode p) {
		Stack<TreeNode> stack = new Stack<TreeNode>();
		TreeNode node = p;
		while (node != null || stack.size() > 0) {
			while (node != null) {
				stack.push(node);// 保存左子树
				node = node.leftchild;
			}
			if (stack.size() > 0) {
				node = stack.pop();
				visted(node);
				node = node.rightchild;
			}
		}
	}
	/**
	 * 后序遍历的非递归实现
	 * @param p
	 */
	public void nonRecPostOrder(TreeNode p) {
		Stack<TreeNode> stack = new Stack<TreeNode>();
		TreeNode node = p;
		while (p != null) {
			for (; p.leftchild != null; p = p.leftchild) {
				stack.push(p);
			}
			while (p != null && (p.rightchild == null || p.rightchild == node)) {
				visted(p);
				node = p;
				if (stack.empty())
					return;
				p = stack.pop();
			}
			// 处理右子树
			stack.push(p);
			p = p.rightchild;
		}
	}

	/**
	 * 释放某一个结点
	 * 左子树,右子树都要释放
	 * @param subTree
	 */
	public static void destory(TreeNode subTree) {
		if (subTree != null) {
			destory(subTree.leftchild);
			destory(subTree.rightchild);
			subTree = null;
		}

	}

}

总结:

    二叉树的基础就是二叉树的三种遍历方式,在接下里的文章还会为各位读者介绍二叉树的镜像,层次遍历等。如果文章中有疏漏请大家在评论中指出,楼主会不胜感激,最后希望我的文章会对你有所帮助,谢谢大家。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值