数据结构之关于树的操作(JAVA实现)(三)

树的基本结构

     public class TreeNode<T>
	{
		public TreeNode<T> leftNode;
		public TreeNode<T> rightNode;
		public T data;

		public TreeNode(T data)
			{
				this.data = data;
			}
	}

1.构建一颗树(本文以表达式树为例,用后缀表达式构建,我在前一篇已近介绍了如何将中序转换为后续表达式)

原理:利用栈。步骤:a.当前字符为字符或者数字,则直接构建一个节点,然后入栈

b.当前字符为操作符,则在栈中取出两个节点,将这两个节点作为孩子节点构建一棵树入栈

c.最后将栈中剩下的唯一节点返回,就是要构建的树

              // 构建一颗字符树,即数学表达式
		public static TreeNode<Character> getTree(String obj)
			{
				// TreeNode<Character> node2=new TreeNode<Character>(null);
				Stack<TreeNode<Character>> stack = new Stack<TreeNode<Character>>();
				for (int i = 0; i < obj.length(); i++)
					{
						char temp = obj.charAt(i);
						if (Character.isLetterOrDigit(temp))// 如果是字母或者数字,那么直接构建一个树,入栈
							{
								TreeNode<Character> node = new TreeNode<Character>(
										temp);
								stack.push(node);
							} else
							// 操作符的话,从栈中取出两个树节点,然后合并成一个节点,操作符为根节点
							{
								TreeNode<Character> node = new TreeNode<Character>(
										temp);
								// 有操作符,栈至少有两个元素
								node.rightNode = stack.pop();
								node.leftNode = stack.pop();
								stack.push(node);
							}
					}
				return stack.pop();
			}

2.用先序,中序,后序打印一颗树,这个没有什么好说的

		/*
		 * 递归 打印一棵树 先序,中序,后序
		 */
		// 先序遍历一棵树,(根左右)
		public String printTreePreOreder(TreeNode<T> node)
			{
				String obj = "";
				if (node != null)
					{
						obj += node.data;
						obj += printTreePreOreder(node.leftNode);
						obj += printTreePreOreder(node.rightNode);
					}
				return obj;
			}

		// 中序遍历一棵树(左根右)
		public String printTreeInfixOreder(TreeNode<T> node)
			{
				String obj = "";
				if (node != null)
					{
						if (node.leftNode != null)
							obj += "(";
						obj += printTreeInfixOreder(node.leftNode);
						obj += node.data;
						obj += printTreeInfixOreder(node.rightNode);
						if (node.rightNode != null)
							obj += ")";
					}
				return obj;
			}

		// 后续遍历一棵树(左右根)
		public String printTreePostOreder(TreeNode<T> node)
			{
				String obj = "";
				if (node != null)
					{
						obj += printTreePostOreder(node.leftNode);
						obj += printTreePostOreder(node.rightNode);
						obj += node.data;
					}
				return obj;
			}

3.得到树的高度(使用递归)

原理:树根的高度=最大的孩子的高度+1

		// 得到一棵树额高度
		public int getHeight()
			{
				if(this==null)
					return 0;
				if (this.leftNode == null && this.rightNode == null)
					return 1;
				int lHeight = this.leftNode.getHeight();
				int rHeight = this.rightNode.getHeight();
				return lHeight > rHeight ? lHeight + 1 : rHeight + 1;
			}

4.打印树的第k层(递归实现)

原理:可以理解为打印根的第k层,即打印根的孩子的第k-1层,当k=0时,可以直接打印出来

		// 打印一棵树的第level层
		public void printTreeAtLevel(TreeNode<T> node, int level)
			{
				if (node == null || level < 0)
					return;
				if (level == 0)// 到达目标层
					System.out.print(node.data);
				printTreeAtLevel(node.leftNode, level - 1);
				print(1);///打印一个空格
				printTreeAtLevel(node.rightNode, level - 1);
			}

5.按层次打印一棵树

我实现了两种方法:

方法一:

知道了树的高度,依次打印出各层的高度。但是这种方法,会在打印任何一层的时候都会从根节点开始,浪费时间

		// 按照树的格式打印一棵树,必须按层次打印
		public void printTree()
			{
				int height = getHeight();
				for (int i = 0; i < height; i++)
					{
						print(height * 2 - i);
						printTreeAtLevel(this, i);
						System.out.println();
					}
			}

方法二:

用两个队列实现,队列1保存所有的同一层叶节点,队列2保存保存队列1的正在访问的孩子节点 ,队列1访问完以后,将队列2加到队列1(此时是空队列)中,再讲队列2清空

public void printTreeByQueue(TreeNode<T> root)
			{
				Queue<TreeNode<T>> queue1, queue2;
				queue1 = new LinkedList<TreeNode<T>>();
				queue2 = new LinkedList<TreeNode<T>>();
				queue1.add(root);
				queue2.add(root);
				while (!queue2.isEmpty())
					{
						queue2.clear();
						while (!queue1.isEmpty())
							{
								TreeNode<T> node = queue1.poll();
								print(2);
								System.out.print(node.data);
								if (node.leftNode != null)
									queue2.add(node.leftNode);
								if (node.rightNode != null)
									queue2.add(node.rightNode);
							}
						queue1.addAll(queue2);
						System.out.println();
					}

			}
时间: 2024-10-18 13:04:20

数据结构之关于树的操作(JAVA实现)(三)的相关文章

数据结构之关于树的操作(树的递归和非递归遍历)-(四补)

前面写了一些关于树的操作,但是没有实现树的遍历的非递归写法. 通常树有四种遍历方法:1.层次遍历(需要用到树的高度,此文没有考虑) 2.前序遍历(根左右):3.中序遍历(左根右):4.后序遍历(左右根) 树的结构如下: 层次遍历:123456789 前序遍历:124895367 中序遍历:849251637 后序遍历:894526731 java代码实现三种遍历的递归和和非递归实现 package com.lip.datastructure.tree; import java.util.Stac

【数据结构】Trie树的应用:查询IP地址的ISP(Java实现)

查询IP地址的ISP 给定一个IP地址,如何查询其所属的ISP,如:中国移动(ChinaMobile),中国电信(ChinaTelecom),中国铁通(ChinaTietong)? 现在网上有ISP的IP地址区段可供下载,比如中国移动的IP地址段 103.20.112.0/22 103.21.176.0/22 111.0.0.0/10 112.0.0.0/10 117.128.0.0/10 120.192.0.0/10 183.192.0.0/10 211.103.0.0/17 211.136.

【经典数据结构】B树与B+树

本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树.与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作.B-tree算法减少定位记录时

Phone List(简单的字典树插入操作)

Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11655    Accepted Submission(s): 3970 Problem Description Given a list of phone numbers, determine if it is consistent in the sense th

数据结构之AVL树

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 在前面的博文中,我们已经介绍了数据结构之二分查找树的相关知识,二分查找的提出主要是为了提高数据的查找效率.同一个元素集合可以对应不同的二分查找树BST,二分查找树的形态依赖于元素的插入顺序.同时我们也已经知道,如果将一个有序的数据集依次插入到二查找树中,此时二分查找树将退化为线性表,此时查找的时间复杂度为o(n).为了防止这一问题的出现,便有了平衡二叉树的存在价值.平衡二叉树从根本上将是为了防止出现斜二叉树的出现,从而进一步提高元素的查找效率,

《数据结构》线段树入门(二)

今天继续介绍——线段树之延迟标记 接上期<数据结构>线段树入门(一):http://www.cnblogs.com/shadowland/p/5870339.html 在上期介绍了线段树的最基本内容(线段树单点修改,区间查询),这次将介绍:区间修改,区间查询. Question: 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述: 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,每行表示操作的个数,如果第一数是1,后接3个正

可持久化数据结构之主席树

转自:http://finaltheory.info/?p=249 HomeACM可持久化数据结构之主席树 06十2013 可持久化数据结构之主席树 Written by FinalTheory on. Posted in ACM 引言 首先引入CLJ论文中的定义: 所谓的“持久化数据结构”,就是保存这个数据结构的所有历史版本,同时利用它们之间的共用数据减少时间和空间的消耗. 本文主要讨论两种可持久化线段树的算法思想.具体实现以及编码技巧. 核心思想 可持久化线段树是利用函数式编程的思想,对记录

【经典数据结构】B树与B+树(转)

本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为"在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树.与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作.B-tree算法减少定位记录时

【数据结构】之顺序表(Java语言描述)

之前总结过使用C语言描述的顺序表数据结构.在C语言类库中没有为我们提供顺序表的数据结构,因此我们需要自己手写,详细的有关顺序表的数据结构描述和C语言代码请见[我的这篇文章]. 在Java语言的JDK中,为我们提供了专门的顺序表的数据结构API-- ArrayList . Java中的ArrayList的基本存储思路和C语言中的思路相似,即将所有元素存储在一个数组中,当数组中的元素个数达到某种标准时,就要扩容.由于顺序表中的其他操作在Java和C中的实现方式大同小异,因此,本文不再详细介绍这些操作