java:树的基本方法

原创 2016年08月28日 16:04:35
package demo_tree;

import java.util.Stack;

public class BinaryTree {
	
	private class Node{
		/**
		 * @param level 层序
		 * @param data 数据域
		 */
		private int level = 0;
		private String data= null;
		private boolean isVisited;
		private Node leftChild;
		private Node rightChild;
		
		public Node() {}

		public Node(int level, String data) {
			this.level = level;
			this.data = data;
			isVisited = false;
			leftChild = null;
			rightChild = null;
		}
		
		public int getLevel() {
			return level;
		}
		public void setLevel(int level) {
			this.level = level;
		}
		public String getData() {
			return data;
		}
		public void setData(String data) {
			this.data = data;
		}		
	}
	
	/** 根节点**/
	private Node root = null;
	
	public BinaryTree(){
		root = new Node(1, "rootNode(A)");
	}
	
	/*
	 * 另一种方法
	 * private Node root = new Node(1, "rootNode(A)");
	 */
	
	/**
	 * 
	 * @Description: 创建一棵二叉树    
	 *  <pre> 
	 *           A 
	 *     B          C 
	 *  D     E            F 
	 *  </pre> 
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:09:49
	 */
	public void createBinTree(){
		Node NodeB= new Node(2, "B");
		Node NodeC = new Node(2, "C");
		Node NodeD = new Node(3, "D");
		Node NodeE = new Node(3, "E");
		Node NodeF = new Node(4, "F");
		
		root.leftChild = NodeB;
		root.rightChild = NodeC;
		NodeB.leftChild = NodeD;
		NodeB.rightChild = NodeE;
		NodeC.rightChild = NodeF;
	}
	
	/**
	 * 
	 * @Description: 树是否为空
	 * @return   
	 * boolean  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:09:39
	 */
	public boolean isEmpty(){
		if(root == null){
			return true;
		}else{
			return false;
		}
		
		/*
		 * 简略写法
		 * return root == null;
		 */
	}
	
	/**
	 * 
	 * @Description: 递归求某个节点的高度
	 * @param node
	 * @return   
	 * int  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:17:26
	 */
	private int height(Node node){
		if(node == null){
			return 0; //递归结束:空树高度为0 
		}else{
			int leftHeight = height(node.leftChild)+1;
			int rightHeight = height(node.rightChild)+1;
			return leftHeight>rightHeight?leftHeight:rightHeight;
		}
	}
	
	/**
	 * 
	 * @Description: 树的高度,即根节点的高度
	 * @return   
	 * int  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:19:01
	 */
	public int height(){
		return height(root);
	}
	
	/**
	 * 
	 * @Description: 递归求某个节点的子孙节点个数
	 * @param node
	 * @return   
	 * int  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:21:08
	 */
	private int size(Node node){
		if(node == null){
			return 0;
		}else{
			int leftSize = size(node.leftChild);
			int rightSize = size(node.rightChild);
			return leftSize + rightSize + 1;
		}
	}
	
	/**
	 * 
	 * @Description: 树的总结点数,即根节点的子孙节点数
	 * @return   
	 * int  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:23:11
	 */
	public int size(){
		return size(root);
	}
	
	/**
	 * 
	 * @Description: 返回双亲节点
	 * @param node
	 * @param element
	 * @return   
	 * Node  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:36:16
	 */
	public Node parent(Node node, Node element){
		if(node == null){
			return null;
		}
		if((node.leftChild == element) || (node.rightChild == element)){
				return node; //返回父结点地址 
		}
		
		Node p;
		//现在左子树中找,如果左子树中没有找到,才到右子树去找 
		if((p = parent(node.leftChild, element)) != null){
			return p;  //递归在左子树中搜索 
		}else{
			return parent(node.rightChild, element);//递归在右子树中搜索 ,右子数允许返回null
		}
	}
	
	/**
	 * 
	 * @Description: 获得左子树,注意判断节点是否为空
	 * @param node
	 * @return   
	 * Node  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:38:46
	 */
	public Node getLeftChild(Node node){
		return (node == null)?null:node.leftChild;
	}
	
	/**
	 * 
	 * @Description: 获得右子树,注意判断节点是否为空
	 * @param node
	 * @return   
	 * Node  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:39:34
	 */
	public Node getRightChild(Node node){
		return (node == null)?null:node.rightChild;
	}
	
	/**
	 * 
	 * @Description: 获得根节点
	 * @return   
	 * Node  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 上午10:40:38
	 */
	public Node getRoot(){
		return root;
	}
	
	/**
	 * 
	 * @Description: 释放某个结点时,该结点的左右子树都已经释放,  
    			所以应该采用后续遍历,当访问某个结点时将该结点的存储空间释放  
	 * @param node   
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 下午2:20:39
	 */
	public void destroy(Node node){
		if(node == null){
			return;
		}else{
			destroy(node.leftChild);
			destroy(node.rightChild);
			node = null;
		}
	}
	
	/**
	 * 
	 * @Description: 节点被访问
	 * @param node   
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 下午2:27:55
	 */
	public void visited(Node node){
		node.isVisited = true;
		System.out.println("node:data"+node.data);
	}
	
	/**
	 * 
	 * @Description: 前序遍历
	 * @param node   
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 下午2:28:22
	 */
	public void preOrder(Node node){
		if(node != null){
			visited(node);
			preOrder(node.leftChild);
			preOrder(node.rightChild);
		}
	}
	
	/**
	 * 
	 * @Description: 中序遍历
	 * @param node   
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 下午2:31:58
	 */
	public void inOrder(Node node){
		if(node != null){
			inOrder(node.leftChild);
			visited(node);
			inOrder(node.rightChild);
		}
	}
	
	/**
	 * 
	 * @Description: 后序遍历
	 * @param node   
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 下午2:32:15
	 */
	public void postOrder(Node node){
		if(node != null){
			postOrder(node.leftChild);
			postOrder(node.rightChild);
			visited(node);
		}
	}
	
	/**
	 * 
	 * @Description: 非递归前序遍历,NLR
	 * @param p   
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 下午2:50:57
	 */
	public void noRecPreOrder(Node p){
		Stack<Node> stack = new Stack<Node>();
		Node node = p;
		while(node != null || stack.size() > 0){
			while(node != null){
				visited(node);
				stack.push(node);
				node = node.leftChild;
			}
			node = stack.pop();
			node = node.rightChild;
		}
	}
	
	/**
	 * 
	 * @Description: 非递归中序遍历,LNR
	 * @param p   
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 下午2:57:45
	 */
	public void noRecInOrder(Node p){
		Stack<Node> stack = new Stack<Node>();
		Node node = p;
		while(node != null || stack.size() > 0){
			while(node != null){
				stack.push(node);
				node = node.leftChild;
			}
			if(stack.size() > 0){
				node = stack.pop();
				visited(node);
				node = node.rightChild;
			}
		}
	}
	
	/**
	 * 
	 * @Description: 非递归后序遍历,LRN
	 * @param p   
	 * void  
	 * @throws
	 * @author Guo
	 * @date 2016年8月28日 下午4:10:38
	 */
	public void noRecPostOrder(Node p){
		Stack<Node> stack = new Stack<Node>();
		Node node = p;
		while(p != null){
			for(;p.leftChild != null ; p=p.leftChild){
				stack.push(p);
			}
			while(p!=null && (p.rightChild==null || p.rightChild==node)){
				visited(p);
				node = p;
				if(stack.empty()){
					return;
				}
				p = stack.pop();
			}
			stack.push(p);
			p = p.rightChild;
		}
	}
	
	public static void main(String[] args) {
		BinaryTree tree = new BinaryTree();
		tree.createBinTree();
		System.out.println("root:"+tree.getRoot());
		System.out.println("heigth:"+tree.height());
		System.out.println("size:"+tree.size());
		System.out.println("isEmpty:"+tree.isEmpty());
		System.out.println("----------");
		System.out.println("preOrder:");
		tree.preOrder(tree.root);
		System.out.println("inOrder:");
		tree.inOrder(tree.root);
		System.out.println("postOrder:");
		tree.postOrder(tree.root);
		System.out.println("----------");
		System.out.println("preOrder:");
		tree.noRecPreOrder(tree.root);
		System.out.println("inOrder:");
		tree.noRecInOrder(tree.root);
		System.out.println("postOrder:");
		tree.noRecPostOrder(tree.root);
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

从观察者模式的角度看RxJava

概述用过Rxjava的朋友都知道它是用观察者模式写的,且用起来的时候一定会有一个Observable(被观察对象)和一个Observer(观察者对象),作者刚接触Rxjava的时候被它的迷の编码方式和...

java构建树,构建tree,组装树结构,通用算法,用到递归算法

java利用递归算法,map和list对树进行组装。

android学习路线

Android大体学习路线,可能有不全,是自己学习总结,供自己复习和新学的朋友们参考

JTable 失去焦点时取消编辑状态

转载地址: http://www.cnblogs.com/aquar/p/3263761.html 当JTable的单元格处于编辑状态时,如果用户触发以下事件,表格就会退出编辑状态,进而调用Ta...

双数组Trie树(DoubleArrayTrie)Java实现

双数组Trie树(DoubleArrayTrie)是一种空间复杂度低的Trie树,应用于字符区间大的语言(如中文、日文等)分词领域。 双数组Trie (Double-Array Trie)结构由日...

Android UI(Button)详解

目录:    1.Button点击事件        1.1 xml中实现onClick属性(不常用)       1.2 创建匿名内部类           ...

树和二叉树在java中

树和二叉树在java中

Android UI(CheckBox)详解

目录: 1.CheckBox应用场景 2.CheckBox一般使用 3.自定义CheckBox 4.CheckBox在ListView中的问题 1.CheckBox应用场景 CheckBox...

Java递归应用:输出树形菜单

树节点类:package cn.com.tree; public class Node { private Integer id; private Integer parentId; priv...

java 多叉树遍历

java 多叉树的遍历 写了二叉的遍历之后,发现多叉也一样的,而且java提供的容器类很方便,手工构造了一颗多叉树。然后再递归遍历。类似于中序遍历吧。 树的节点类: Java代码 <a title="...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)