树(Tree)以及二叉树的遍历

树(tree) 是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

树的特点:

  • 每个节点有零个或多个子节点;
  • 没有父节点的节点称为根节点;
  • 每一个非根节点有且只有一个父节点;
  • 除了根节点外,每个子节点可以分为多个不相交的子树;

常用到的术语:

  • 节点的度:一个节点含有的子树的个数称为该节点的度(上图 A->2 B->3 J->0)
  • 树的度:一棵树中,最大的节点的度称为树的度(上图B节点 3个度 最大)
  • 叶节点或终端节点:度为零的节点(上图A K O P)
  • 父亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点(上图A是BC的父节点 B是DEF的父节点)
  • 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点(上图BC是A的子节点 DEF是B的子节点)`;
  • 兄弟节点:具有相同父节点的节点互称为兄弟节点(上图BC DEF LM是相互的兄弟节点 )
  • 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推(上图A为第1层 BC第2层 DEFGH第三层 ...)
  • 树的高度或深度 :树中节点的最大层次(上图为5层)
  • 堂兄弟节点:父节点在同一层的节点互为堂兄弟(上图FG为堂兄弟节点)
  • 森林:由m(m>=0)棵互不相交的树的集合称为森林;

种类

  • 无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树;
  • 有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树;
    • 二叉树:每个节点最多含有两个子树的树称为二叉树;
      • 完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地紧密排列,这样的二叉树被称为完全二叉树;
        • 满二叉树:所有叶节点都在最底层的完全二叉树(下图所示);
      • 平衡二叉树:当且仅当任何节点的两棵子树的高度差不大于1的二叉树;
      • 排序二叉树(二叉查找树)(英语:Binary Search Tree),也称二叉搜索树、有序二叉树);
  • ……

二叉树的性质:

  1. 在二叉树的第i层上至多有2^(i-1)个结点。  2. 深度为k的二叉树之多有(2^k)-1个结点。
  2. 对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点树为n2,则n0=n2+1。
  3. 具有n个结点的完全二叉树的深度为(logn)+1。
  4. 如果对一棵有n个结点的完全二叉树的结点按层序号遍历,对任意结点i有: 如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点i/2。 如果2i>n,则结点i无左孩子;否则其左孩子是结点2i。 如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1.

二叉树的表示方法:

双亲表示法 在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。这种方式返回来找父节点不方便

孩子表示法:也不助于查找父节点

孩子兄弟表示法:

比较好的表示方案:借用HashMap的思想,一个组head表示父节点,一组都是该父节点的子节点。

二叉树的遍历:

  • 前序遍历:若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。 中–>左–>右

  • 中序遍历:若二叉树为空,则空操作返回,否则从根结点开始,中序遍历根节点的左子树,然后访问根结点,再中序遍历根结点的右子树。左–>中–>右

  • 后序遍历:若二叉树为空,则空操作返回,否则从左到右先叶子后节点的方式遍历访问左子树和右子树,最后是访问根结点。左–>右–>中

  • 层次遍历:若二叉树为空,则空操作返回,否则从树的第一层开始,也就是根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。一层一层的遍历

JAVA实现一个简单的二叉树的遍历

public class BinaryTree {
	private TreeNode  root = null;
	
	public BinaryTree(){
		root = new TreeNode(1, "A");
	}
	
	/**
	 * 构建二叉树
	 *         A
	 *     B       C
	 * D      E        F
	 */
	public void createBinaryTree(){
		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;
	}
	
	/**
	 * 求二叉树的高度
	 * @author Administrator
	 *
	 */
	public int getHeight(){
		return getHeight(root);
	}
	
	private int getHeight(TreeNode node) {
		if(node == null){
			return 0;
		}else{
			int i = getHeight(node.leftChild);
			int j = getHeight(node.rightChild);
			return (i<j)?j+1:i+1;
		}
	}

	/**
	 * 获取二叉树的结点数
	 * @author Administrator
	 *
	 */
	public int getSize(){
		return getSize(root);
	}
	
	
	private int getSize(TreeNode node) {
		if(node == null){
			return 0;
		}else{
			return 1+getSize(node.leftChild)+getSize(node.rightChild);
		}
	}

	/**
	 * 前序遍历——迭代
	 * @author Administrator
	 *
	 */
	public void preOrder(TreeNode node){
		if(node == null){
			return;
		}else{
			System.out.println("preOrder data:"+node.getData());
			preOrder(node.leftChild);
			preOrder(node.rightChild);
		}
	}
	
	/**
	 * 前序遍历——非迭代
	 */
	
	public void nonRecOrder(TreeNode node){
		if(node == null){
			return;
		}
		Stack<TreeNode> stack = new Stack<TreeNode>();
		stack.push(node);
		while(!stack.isEmpty()){
			//出栈和进栈
			TreeNode n = stack.pop();//弹出根结点
			//压入子结点
			System.out.println("nonRecOrder data"+n.getData());
			if(n.rightChild!=null){
				stack.push(n.rightChild);
				
			}
			if(n.leftChild!=null){
				stack.push(n.leftChild);
			}
		}
	}
	/**
	 * 中序遍历——迭代
	 * @author Administrator
	 *
	 */
	public void midOrder(TreeNode node){
		if(node == null){
			return;
		}else{
			midOrder(node.leftChild);
			System.out.println("midOrder data:"+node.getData());
			midOrder(node.rightChild);
		}
	}
	
	/**
	 * 后序遍历——迭代
	 * @author Administrator
	 *
	 */
	public void postOrder(TreeNode node){
		if(node == null){
			return;
		}else{
			postOrder(node.leftChild);
			postOrder(node.rightChild);
			System.out.println("postOrder data:"+node.getData());
		}
	}
	public class TreeNode{
		private int index;
		private String data;
		private TreeNode leftChild;
		private TreeNode rightChild;
		
	
		public int getIndex() {
			return index;
		}


		public void setIndex(int index) {
			this.index = index;
		}


		public String getData() {
			return data;
		}


		public void setData(String data) {
			this.data = data;
		}


		public TreeNode(int index,String data){
			this.index = index;
			this.data = data;
			this.leftChild = null;
			this.rightChild = null;
		}
	}
	
	
	public static void main(String[] args){
		BinaryTree binaryTree = new BinaryTree();
		binaryTree.createBinaryTree();
		int height = binaryTree.getHeight();
		System.out.println("treeHeihgt:"+height);
		int size = binaryTree.getSize();
		System.out.println("treeSize:"+size);
//		binaryTree.preOrder(binaryTree.root);
//		binaryTree.midOrder(binaryTree.root);
//		binaryTree.postOrder(binaryTree.root);
		binaryTree.nonRecOrder(binaryTree.root);
	}
}

水平有限,文中有什么不对或者有什么建议希望大家能够指出,谢谢!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python专栏

【数据结构与算法】一起搞定面试中的二叉树题目(二)

22830
来自专栏向治洪

数据结构之二叉树

树 定义:满足以下条件的就是树: 1. 有且仅有一个特定的称为根Root的结点。 2. 当n>1时,其余结点可分为m(m>0)个互不相交的有限集,其...

217100
来自专栏菩提树下的杨过

数据结构C#版笔记--树与二叉树

                图1 上图描述的数据结构就是“树”,其中最上面那个圈圈A称之为根节点(root),其它圈圈称为节点(node),当然root可以...

31980
来自专栏java学习

让你更好的理解什么是二叉树?

二叉树 6.2.1 二叉树的概念 二叉树(Binary Tree)是结点的有限集合,这个集合或者为空,或者是由一个根结点和两颗互不相交的分别称为左子树和右子树的...

837110
来自专栏用户画像

4.3.1 二叉树的遍历

所谓二叉树的遍历,是指按照某条搜索路径访问树中的每个结点,使得每个几点均被访问一次,而且仅被访问一次。

9420
来自专栏软件开发 -- 分享 互助 成长

二叉排序树和平衡二叉树

二叉排序树又称二叉查找树或二叉搜索树。 它一棵空树或者是具有下列性质: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,...

223100
来自专栏熊二哥

深入入门系列--Data Structure--04树

终于有机会重新回头学习一下一直困扰自身多年的数据结构了,赶脚棒棒哒。一直以来,对数据结构的掌握基本局限于线性表,稍微对树有一丢丢了解,而对于图那基本上就是不懂(...

19690
来自专栏武培轩的专栏

剑指Offer-把二叉树打印成多行

package Tree; import java.util.ArrayList; import java.util.LinkedList; import ...

39740
来自专栏desperate633

LintCode 二叉树的层次遍历 II题目代码

给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历)

10140
来自专栏灯塔大数据

每周学点大数据 | No.24二叉搜索树回顾(一)

No.24期 二叉搜索树回顾(一) Mr. 王:接下来我们谈一谈外存查找结构。内存中的查找结构最典型的就是二查搜索树了。这里我们先来简单地认识一下关于二叉树...

36850

扫码关注云+社区

领取腾讯云代金券