`
啸笑天
  • 浏览: 3435569 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

【code】java二叉树的实现

阅读更多

二叉树的顺序存储

public class ArrayBinTree<T>
{
	//使用数组来记录该树的所有节点
	private Object[] datas;
	private int DEFAULT_DEEP = 8;
	//保存该树的深度
	private int deep;
	private int arraySize;
	//以默认的深度来创建二叉树
	public ArrayBinTree()
	{
		this.deep = DEFAULT_DEEP;
		this.arraySize = (int)Math.pow(2 , deep) - 1;
		datas = new Object[arraySize];
	}
	//以指定深度来创建二叉树
	public ArrayBinTree(int deep)
	{
		this.deep = deep;
		this.arraySize = (int)Math.pow(2 , deep) - 1;
		datas = new Object[arraySize];
	}
	//以指定深度,指定根节点创建二叉树
	public ArrayBinTree(int deep , T data)
	{
		this.deep = deep;
		this.arraySize = (int)Math.pow(2 , deep) - 1;
		datas = new Object[arraySize];
		datas[0] = data;
	}
	/**
	 * 为指定节点添加子节点。
	 * @param index 需要添加子节点的父节点的索引
	 * @param data 新子节点的数据
	 * @param left 是否为左节点
	 */
	public void add(int index , T data , boolean left)
	{
		if (datas[index] == null)
		{
			throw new RuntimeException(index + "处节点为空,无法添加子节点");
		}
		if (2 * index + 1 >= arraySize)
		{
			throw new RuntimeException("树底层的数组已满,树越界异常");
		}
		//添加左子节点
		if (left)
		{
			datas[2 * index + 1] = data;
		}
		else
		{
			datas[2 * index + 2] = data;
		}
	}
	//判断二叉树是否为空。
	public boolean empty()
	{
		//根据根元素来判断二叉树是否为空
		return datas[0] == null;
	}
	//返回根节点。
	public T root()
	{
		return (T)datas[0] ;
	}
	//返回指定节点(非根节点)的父节点。
	public T parent(int index)
	{
		return (T)datas[(index - 1) / 2] ;
	}
	//返回指定节点(非叶子)的左子节点。当左子节点不存在时返回null
	public T left(int index)
	{
		if (2 * index + 1 >= arraySize)
		{
			throw new RuntimeException("该节点为叶子节点,无子节点");
		}
		return (T)datas[index * 2 + 1] ;
	}
	//返回指定节点(非叶子)的右子节点。当右子节点不存在时返回null
	public T right(int index)
	{
		if (2 * index + 1 >= arraySize)
		{
			throw new RuntimeException("该节点为叶子节点,无子节点");
		}
		return (T)datas[index * 2 + 2] ;
	}
	//返回该二叉树的深度。
	public int deep(int index)
	{
		return deep;
	}
	//返回指定节点的位置。
	public int pos(T data)
	{
		//该循环实际上就是按广度遍历来搜索每个节点
		for (int i = 0 ; i < arraySize ; i++)
		{
			if (datas[i].equals(data))
			{
				return i;
			}
		}
		return -1;
	}
	public String toString()
	{
		return java.util.Arrays.toString(datas);
	}
	
	public static void main(String[] args) 
	{
		ArrayBinTree<String> binTree = 
			new ArrayBinTree<String>(4, "根");
		binTree.add(0 , "第二层右子节点" , false);//是从0位置开始
		binTree.add(2 , "第三层右子节点" , false);
		binTree.add(6 , "第四层右子节点" , false);
		System.out.println(binTree);
	}
}
 

二叉树的链表存储

public class TwoLinkBinTree<E>
{
	public static class TreeNode
	{
		Object data;
		TreeNode left;
		TreeNode right;
		public TreeNode()
		{
		}
		public TreeNode(Object data)
		{
			this.data = data;
		}
		public TreeNode(Object data , TreeNode left
			, TreeNode right)
		{
			this.data = data;
			this.left = left;
			this.right = right;
		}
	}
	private TreeNode root;
	//以默认的构造器来创建二叉树
	public TwoLinkBinTree()
	{
		this.root = new TreeNode();
	}
	//以指定根元素来创建二叉树
	public TwoLinkBinTree(E data)
	{
		this.root = new TreeNode(data);
	}
	/**
	 * 为指定节点添加子节点。
	 * @param index 需要添加子节点的父节点的索引
	 * @param data 新子节点的数据
	 * @param isLeft 是否为左节点
	 * @return 新增的节点
	 */
	public TreeNode addNode(TreeNode parent , E data
		, boolean isLeft)
	{
		if (parent == null)
		{
			throw new RuntimeException(parent +
				"节点为null,无法添加子节点");
		}
		if (isLeft && parent.left != null)
		{
			throw new RuntimeException(parent +
				"节点已有左子节点,无法添加左子节点");
		}
		if (!isLeft && parent.right != null)
		{
			throw new RuntimeException(parent +
				"节点已有右子节点,无法添加右子节点");
		}
		TreeNode newNode = new TreeNode(data);
		if (isLeft)
		{
			//让父节点的left引用指向新节点
			parent.left = newNode;
		}
		else
		{
			//让父节点的left引用指向新节点
			parent.right = newNode;
		}
		return newNode;
	}
	//判断二叉树是否为空。
	public boolean empty()
	{
		//根据根元素来判断二叉树是否为空
		return root.data == null;
	}
	//返回根节点。
	public TreeNode root()
	{
		if (empty())
		{
			throw new RuntimeException("树为空,无法访问根节点");
		}
		return root;
	}
	//返回指定节点(非根节点)的父节点。
	public E parent(TreeNode node)
	{
		//对于二叉链表存储法,如果要访问指定节点的父节点必须遍历二叉树
		return null;
	}
	//返回指定节点(非叶子)的左子节点。当左子节点不存在时返回null
	public E leftChild(TreeNode parent)
	{
		if (parent == null)
		{
			throw new RuntimeException(parent +
				"节点为null,无法添加子节点");
		}
		return parent.left == null ? null : (E)parent.left.data;
	}
	//返回指定节点(非叶子)的右子节点。当右子节点不存在时返回null
	public E rightChild(TreeNode parent)
	{
		if (parent == null)
		{
			throw new RuntimeException(parent +
				"节点为null,无法添加子节点");
		}
		return parent.right == null ? null : (E)parent.right.data;
	}
	//返回该二叉树的深度。
	public int deep()
	{
		//获取该树的深度
		return deep(root); 
	}
	//这是一个递归方法:每棵子树的深度为其所有子树的最大深度 + 1
	private int deep(TreeNode node)
	{
		if (node == null)
		{
			return 0;
		}
		//没有子树
		if (node.left == null
			&& node.right == null)
		{
			return 1;
		}
		else
		{
			int leftDeep = deep(node.left);
			int rightDeep = deep(node.right);
			//记录其所有左、右子树中较大的深度
			int max = leftDeep > rightDeep ? 
				leftDeep : rightDeep;
			//返回其左右子树中较大的深度 + 1
			return max + 1;
		}
	}
	
	public static void main(String[] args) 
    {
        TwoLinkBinTree<String> binTree = new TwoLinkBinTree("根节点");
		//依次添加节点
		TwoLinkBinTree.TreeNode tn1 = binTree.addNode(binTree.root()
			,  "第二层左节点" , true);
		TwoLinkBinTree.TreeNode tn2 = binTree.addNode(binTree.root()
			, "第二层右节点" ,false );
		TwoLinkBinTree.TreeNode tn3 = binTree.addNode(tn2 
			, "第三层左节点" , true);
		TwoLinkBinTree.TreeNode tn4 = binTree.addNode(tn2
			, "第三层右节点" , false);
		TwoLinkBinTree.TreeNode tn5 = binTree.addNode(tn3
			, "第四层左节点" , true);
		System.out.println("tn2的左子节点:" + binTree.leftChild(tn2));
		System.out.println("tn2的右子节点:" + binTree.rightChild(tn2));
		System.out.println(binTree.deep());
    }
}
 

二叉树的三叉链表存储

public class ThreeLinkBinTree<E>
{
	public static class TreeNode
	{
		Object data;
		TreeNode left;
		TreeNode right;
		TreeNode parent;
		public TreeNode()
		{
		}
		public TreeNode(Object data)
		{
			this.data = data;
		}
		public TreeNode(Object data , TreeNode left
			, TreeNode right , TreeNode parent)
		{
			this.data = data;
			this.left = left;
			this.right = right;
			this.parent = parent;
		}
	}
	private TreeNode root;
	//以默认的构造器来创建二叉树
	public ThreeLinkBinTree()
	{
		this.root = new TreeNode();
	}
	//以指定根元素来创建二叉树
	public ThreeLinkBinTree(E data)
	{
		this.root = new TreeNode(data);
	}
	/**
	 * 为指定节点添加子节点。
	 * @param index 需要添加子节点的父节点的索引
	 * @param data 新子节点的数据
	 * @param isLeft 是否为左节点
	 * @return 新增的节点
	 */
	public TreeNode addNode(TreeNode parent , E data
		, boolean isLeft)
	{
		if (parent == null)
		{
			throw new RuntimeException(parent +
				"节点为null,无法添加子节点");
		}
		if (isLeft && parent.left != null)
		{
			throw new RuntimeException(parent +
				"节点已有左子节点,无法添加左子节点");
		}
		if (!isLeft && parent.right != null)
		{
			throw new RuntimeException(parent +
				"节点已有右子节点,无法添加右子节点");
		}
		TreeNode newNode = new TreeNode(data);
		if (isLeft)
		{
			//让父节点的left引用指向新节点
			parent.left = newNode;
		}
		else
		{
			//让父节点的left引用指向新节点
			parent.right = newNode;
		}
		//让新节点的parent引用到parent节点
		newNode.parent = parent;
		return newNode;
	}
	//判断二叉树是否为空。
	public boolean empty()
	{
		//根据根元素来判断二叉树是否为空
		return root.data == null;
	}
	//返回根节点。
	public TreeNode root()
	{
		if (empty())
		{
			throw new RuntimeException("树为空,无法访问根节点");
		}
		return root;
	}
	//返回指定节点(非根节点)的父节点。
	public E parent(TreeNode node)
	{
		if (node == null)
		{
			throw new RuntimeException(node +
				"节点为null,无法访问其父节点");
		}
		return (E)node.parent.data;
	}
	//返回指定节点(非叶子)的左子节点。当左子节点不存在时返回null
	public E leftChild(TreeNode parent)
	{
		if (parent == null)
		{
			throw new RuntimeException(parent +
				"节点为null,无法添加子节点");
		}
		return parent.left == null ? null : (E)parent.left.data;
	}
	//返回指定节点(非叶子)的右子节点。当右子节点不存在时返回null
	public E rightChild(TreeNode parent)
	{
		if (parent == null)
		{
			throw new RuntimeException(parent +
				"节点为null,无法添加子节点");
		}
		return parent.right == null ? null : (E)parent.right.data;
	}
	//返回该二叉树的深度。
	public int deep()
	{
		//获取该树的深度
		return deep(root); 
	}
	//这是一个递归方法:每棵子树的深度为其所有子树的最大深度 + 1
	private int deep(TreeNode node)
	{
		if (node == null)
		{
			return 0;
		}
		//没有子树
		if (node.left == null
			&& node.right == null)
		{
			return 1;
		}
		else
		{
			int leftDeep = deep(node.left);
			int rightDeep = deep(node.right);
			//记录其所有左、右子树中较大的深度
			int max = leftDeep > rightDeep ? 
				leftDeep : rightDeep;
			//返回其左右子树中较大的深度 + 1
			return max + 1;
		}
	}
	
	public static void main(String[] args) 
    {
        ThreeLinkBinTree<String> binTree = new ThreeLinkBinTree("根节点");
		//依次添加节点
		ThreeLinkBinTree.TreeNode tn1 = binTree.addNode(binTree.root()
			,  "第二层左节点" , true);
		ThreeLinkBinTree.TreeNode tn2 = binTree.addNode(binTree.root()
			, "第二层右节点" ,false );
		ThreeLinkBinTree.TreeNode tn3 = binTree.addNode(tn2 
			, "第三层左节点" , true);
		ThreeLinkBinTree.TreeNode tn4 = binTree.addNode(tn2
			, "第三层右节点" , false);
		ThreeLinkBinTree.TreeNode tn5 = binTree.addNode(tn3
			, "第四层左节点" , true);
		System.out.println("tn2的父节点:" + binTree.parent(tn2));
		System.out.println("tn2的左子节点:" + binTree.leftChild(tn2));
		System.out.println("tn2的右子节点:" + binTree.rightChild(tn2));
		System.out.println(binTree.deep());
    }
}
 
分享到:
评论

相关推荐

    java二叉树源码-cuda-word2vec:CBOW模型的cuda实现(word2vec)

    java二叉树源码cuda-word2vec CBOW模型的cuda实现 特征 与 Nvidia GPU 并行加速 对于任意大的训练集需要恒定的内存 流实现不需要训练数据随机访问 自动验证并在训练期间显示验证数据负对数似然 支持自定义词二叉树...

    java二叉树源码-leetcode:Java中的Leetcode解决方案、代码框架和单元测试(进行中)

    java二叉树源码 来自 . (进行中) root |--- doc | |-- category.md // category for problems in leetcode | |-- problems.tsv // searchable tsv file listing problems from leetcode | |-- road.md // general ...

    java二叉树源码-bda:二进制可执行文件中的程序员去匿名化

    java二叉树源码从可执行二进制文件中去匿名化程序员的初始文档。 详情见论文: 请引用:(bibtex 条目)@inproceedings{caliskan2018coding,title={当编码风格在编译中幸存时:从可执行二进制文件中去除程序员的...

    JAVA面试题最全集

    请用java写二叉树算法,实现添加数据形成二叉树功能,并以先序的方式打印出来. 43.请写一个java程序实现线程连接池功能? 44.给定一个C语言函数,要求实现在java类中进行调用。 45.如何获得数组的长度? 46....

    Java面试宝典-经典

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    汉诺塔java源码-code-challenges:享受编码和解决问题的乐趣

    BinaryTree:二叉树实现源代码: LinkedList:简单的链表实现源代码: 堆栈:基本堆栈实现源代码: 卡片:洗一副卡片。 源代码: 波兰逆向符号:解决问题源代码: 河内塔:解决问题源代码: 排序算法游乐场 ...

    Java面试宝典2010版

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    leetcode107java-java-leet-code:持续更新leet-code题解

    java-leet-code 持续更新leet-code题解 容易(92) # 标题 标签 001 数组哈希表 007 细绳 008 字符串数组 014 字符串数组 019 链表 020 堆 021 链表 026 大批 028 字符串数组 035 数组哈希表 036 数组哈希集 048 ...

    java面试题

    请用java写二叉树算法,实现添加数据形成二叉树功能,并以先序的方式打印出来. 119 84.12. 请写一个java程序实现线程连接池功能? 122 84.13. 编一段代码,实现在控制台输入一组数字后,排序后在控制台输出; 122 ...

    java面试题大全(2012版)

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    疯狂的java讲义源码-CodeAndDecodeByHuffman:数据结构课设——HuffMan编码和解码(Java)

    疯狂的java讲义 源码 课题:《哈夫曼树编码解码》 一、实验内容 运用哈夫曼编码的相关知识对任意文本文件进行编码、解码。 二、需要用的数据结构以及实现思路 需要用到二叉树、HuffMan树、递归等数据结构 二叉树 在...

    最新Java面试宝典pdf版

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    Java面试笔试资料大全

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    java面试宝典2012

    5、说明生活中遇到的二叉树,用java实现二叉树 73 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 78 7、写一个Singleton出来。 81 8、递归算法题1 84 9、递归...

    JAVA面试宝典2010

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    Java面试宝典2012新版

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    Java面试宝典2012版

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、...

Global site tag (gtag.js) - Google Analytics