一、树的定义:

1、树:树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一颗非空树中:

(1)有且仅有一个特定的称为根(Root)的结点;

(2)当n>1是,其余结点可分为m(m>0)个互不相交的有限集T1,T2,......Tn,其中每一个集合本身又是一棵树,并且称为根的子树   (SubTree).

Java树的loadUIToDiv java树的定义_二叉树

 2、结点的度:结点拥有的子树称为结点的度。度为0的结点称为叶子结点或终端结点,度不为0的结点称为非终端结点或分支结点。除根结点以外,分支结点也称为内部结点。树的度是树内各结点的度的最大值。

Java树的loadUIToDiv java树的定义_结点_02

3、层次与深度:结点的层次(level)从根考试定义起,根为第一层,根的孩子为第二层。若某结点在第1层,则其子树的根就在第i+1层。其双亲在同一层的结点互为堂兄弟。如下图的D、E、F是堂兄弟,而G、H、I、J也是。是中结点的最大层次称为树的深度(Depth)或高度,当前树的深度为4。

Java树的loadUIToDiv java树的定义_Java树的loadUIToDiv_03

二、二叉树

1、二叉树是一种特殊的树,它的特点是每个结点最多有两个子树(即二叉树的度不能大于2),并且二叉树的子树有左右之分,其次序不能颠倒。

2、一棵深度为k 且有2^k -1 个结点的二叉树称为满二叉树。

3、如果有深度为k 的,有n 个结点的二叉树,如果其每一个结点都与深度为k 的满二叉树中编号从1 至n 的结点一一对应,则称之为完全二叉树。

二叉树性质: 
性质1:在二叉树的第i 层上最多有2^(i – 1)个结点(i>=1)。

性质2:深度为k 的二叉树至多有2^i – 1 个结点(k>=1)。 

性质3:对如何一颗二叉树T,如果其终端结点数为

Java树的loadUIToDiv java树的定义_二叉树_04

,度为2的结点数为

Java树的loadUIToDiv java树的定义_二叉树_05

,则

Java树的loadUIToDiv java树的定义_Java树的loadUIToDiv_06

。性质4:具有n个结点的完全二叉树深度为

Java树的loadUIToDiv java树的定义_Java树的loadUIToDiv_07

([x]N表示不大于X的最大整数)。性质5:如果对一颗有n个结点的完全二叉树(其深度为

Java树的loadUIToDiv java树的定义_Java树的loadUIToDiv_07

)的结点按层序编号(从第1层到底

Java树的loadUIToDiv java树的定义_Java树的loadUIToDiv_07

层,每层从左到右),对任意一个结点i(1<=i<=n)有:

   1):如果i=1.则结点i是二叉树的根,无双亲;如果i>1,在其双亲是结点[i/2]

   2):如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i

   3):如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1

4、二叉树的遍历:(非常重要)

前序遍历:根 左 右;

结果为:A   B   D   G   H   C   E   I   F

Java树的loadUIToDiv java树的定义_子树_10

中序遍历:左 根 右;

结果为:G   D   H   B   A   E   I   C   F

Java树的loadUIToDiv java树的定义_Java树的loadUIToDiv_11

后序遍历:左 右 根;

结果为:G   H   D   B   I   E   F   C   A

 

Java树的loadUIToDiv java树的定义_二叉树_12

代码如下:

public class BinaryTree {
	
	/**
	 * BinaryTree 的节点数据结构
	 */
	private class TreeNode{
		private int key = 0;
		private String data = null;
		private boolean isVisited = false;
		private TreeNode leftChild = null;
		private TreeNode rightChild = null;
		
		public TreeNode(){}
		public TreeNode(int key,String data){
			this.key = key;
			this.data = data;
			this.leftChild = null;
			this.rightChild = null;
		}
	}
	
	//获取根节点
	public TreeNode getRoot() {
		return root;
	}
 
	public void setRoot(TreeNode root) {
		this.root = root;
	}
 
	
	//定义根节点
	private TreeNode root = null;
	public BinaryTree(){
		root = new TreeNode(1,"A");
	}
	
	/**
	 * 创建一棵二叉树
	 */
	public void createBinaryTree(TreeNode root){
		TreeNode nodeB = new TreeNode(2,"B");
		TreeNode nodeC = new TreeNode(3,"C");
		TreeNode nodeD = new TreeNode(4,"D");
		TreeNode nodeE = new TreeNode(5,"E");
		TreeNode nodeF = new TreeNode(6,"F");
		root.leftChild = nodeB;
		root.rightChild = nodeC;
		nodeB.leftChild = nodeD;
		nodeB.rightChild = nodeE;
		nodeC.rightChild = nodeF;
		
	}
	
	/**
	 * 前序遍历
	 */
	public void preOrder(TreeNode node){
		if(node != null){
			visited(node);
			preOrder(node.leftChild);
			preOrder(node.rightChild);
		}
	}
	/**
	 * 中序遍历
	 * @param node
	 */
	
	public void inOrder(TreeNode node){
		if(node != null){
			preOrder(node.leftChild);
			visited(node);
			preOrder(node.rightChild);
		}
	}
	/**
	 * 后序遍历
	 * @param node
	 */
	
	public void postOrder(TreeNode node){
		if(node != null){
			preOrder(node.leftChild);
			preOrder(node.rightChild);
			visited(node);
		}
	}
	/**
	 * 非递归前序遍历
	 * @param node
	 */
	
	public void nonRecPreOrder(TreeNode node){
		Stack<TreeNode> stack = new Stack<>();
		TreeNode pNode = node;
		while(pNode != null || stack.size()>0){
			while(pNode != null){
				visited(pNode);
				stack.push(pNode);
				pNode = pNode.leftChild;
			}
			if(stack.size()>0){
				pNode = stack.pop();
				pNode = pNode.rightChild;
			}
		}
	}
	/**
	 * 非递归中序遍历
	 * @param node
	 */
	
	public void nonRecInOrder(TreeNode node){
		Stack<TreeNode> stack = new Stack<>();
		TreeNode pNode = node;
		while(pNode != null || stack.size()>0){
			while(pNode != null){
				stack.push(pNode);
				pNode = pNode.leftChild;
			}
			if(stack.size()>0){
				pNode = stack.pop();
				visited(pNode);
				pNode = pNode.rightChild;
			}
		}
	}
	
	/**
	 * 非递归后序遍历
	 * @param pNode
	 */
	public void nonRecPostOrder(TreeNode pNode){
		Stack<TreeNode> stack = new Stack<>();
		TreeNode node = pNode;
		while(pNode != null){
			//左子树入栈
			while(pNode.leftChild != null){
				stack.push(pNode);
				pNode = pNode.leftChild;
			}
			//当前节点无右子树或者右子树已输出
			while(pNode != null && (pNode.rightChild == null || pNode.rightChild == node)){
				visited(pNode);
				//记录上一个已输出的节点
				node = pNode;
				if(!stack.isEmpty()){
					pNode = stack.pop();
				}else{
					return;
				}
			}
			//右子树入栈
			stack.push(pNode);
			pNode = pNode.rightChild;	
		}
	}
 
	private void visited(TreeNode node) {
		node.isVisited = true;
		System.out.println(node.data+","+node.key);
	}
	
	/**
	 * 计算树的高度
	 */
	private int height(TreeNode node){
		if(node == null){
			return 0;
		}else{
			int i = height(node.leftChild);
			int j = height(node.rightChild);
			return (i<j)?j+1:i+1;
		}
	}
	
	/**
	 * 计算树的节点数
	 * @param node
	 * @return 树的节点数
	 */
	
	private int size(TreeNode node){
		if(node == null){
			return 0;
		}else{
			return 1+size(node.leftChild)+size(node.rightChild);
		}
	}
	
	
	
	public static void main(String[] args) {
		BinaryTree binaryTree = new BinaryTree();
		TreeNode root = binaryTree.root;
		binaryTree.createBinaryTree(root);
		System.out.println(binaryTree.height(root));
		System.out.println(binaryTree.size(root));
		binaryTree.preOrder(root);
		System.out.println("*******");
		binaryTree.nonRecPreOrder(root);
		System.out.println("*******");
		binaryTree.nonRecInOrder(root);
		System.out.println("-------------");
		binaryTree.nonRecPostOrder(root);
	}
	
}