首先什么是树结构?

树是一种描述非线性层次关系的数据结构,树是n个数据结点的集合,这些集结点包含一个根节点,根节点下有着互相不交叉的子集合,这些子集合便是根节点的子树。

树的特点

  • 在一个树结构中,有且仅有一个结点没有直接前驱,它就是根节点。
  • 除了根节点,其他结点有且只有一个直接前驱
  • 每个结点可以有任意多个直接后继

树的名词解释

  • 结点的度:一个结点包含子树的数量。
  • 树的度:该树所有结点中最大的度。
  • 兄弟结点:具有同一父结点的结点称为兄弟结点。
  • 树的深度(高度):叶子结点的深度(高度)为1,根节点深度(高度)最高;
  • 层数:从树根开始算,树根是第一层,以此类推。
  • 森林:由多个树组成

只说干货,现在直接复习最重要的——二叉树

二叉树

二叉树是一种超级超级超级重要的数据结构!也是树表家族最为基础的结构
先看看定义:二叉树嘛,每个结点最多只能有二棵子树,二叉树的子树有左右之分,次序不能颠倒
再看看完全二叉树的性质:

  • 第i层至多有 2的i次方减一 个结点
  • 深度为k的二叉树至多有2k-1个结点
  • 任意二叉树,度为0的节点数=度为2的节点数+1;
  • 如果i为父亲的编号,则孩子的编号为2i和2i+1;
  • 如果孩子编号为n,父亲结点编号为k/2,向下取整

关于树的度:
二叉树中连接节点和节点的线就是度
上面说过——度为0的节点数为度为2的节点数加1,即n0=n2+1
这个公式的推理方法如下:
设:
k:总度数
k+1:总节点数
n0:度为0的节点
n1:度为1的节点
n2:度为二的节点
根据二叉树中度和节点的守衡原理,可列出以下一组方程:
k=n2*2+n1;
k+1=n2+n1+n0;
根据方程可以求出n0=n2+1

基本概念不说,研究一下二叉树的遍历

二叉树的遍历

首先,我们看看前序、中序、后序遍历的特性:
前序遍历: (根——左——右)
1.访问根节点
2.前序遍历左子树
3.前序遍历右子树
中序遍历: (左——根——右)
1.中序遍历左子树
2.访问根节点
3.中序遍历右子树
后序遍历: (左——右——根)
1.后序遍历左子树
2.后序遍历右子树
3.访问根节点

要知道:
中序遍历是很重要的一个判断参照!如果只给我们前序遍历和后序遍历的结果,我们将无法推导出唯一的树。
给我们前序遍历和中序遍历,我们可以推出中序
给我们后序遍历和中序遍历,我们可以推出中序


好了,已经写了很多但是并没有拿出来什么真干货,接下来用代码写一下关于树的操作,这里先讲好——对于“树”这个运行结构,最重要的概念是“递归”,要想把树的概念理解好,必须先培养递归的思想。我向这篇文章:写递归函数的正确思想学习了一下,真的写的很棒,条理清晰而且有详有略。在这之后我就希望通过自己亲手敲代码的方式去学习,但是研究了两天,依然进展比较一般,最后通过研究各方博客的C代码,从而找到了思路。不再说废话了,这东西,必须通过自己动手敲才能有收获,好的接下来就要拿代码出来了。这里感谢这片文章二叉树题目实现
以下则是用java代码去写的,注解已经很详细,没有分开写,时不时有新体会也会去添加或修改:


二叉树类:

相关操作:
 * 1.获取节点数
* 2.求深度
* 3. 前序遍历,中序遍历,后序遍历
* 4.分层遍历二叉树(按层次从上往下,从左往右)
* 5.求二叉树第K层的节点个数
* 6.求二叉树中叶子节点的个数
* 7. 判断两棵二叉树是否结构相同

实现:

 package com.myutil.tree1;

 /*
* 1.获取节点数
* 2.求深度
* 3. 前序遍历,中序遍历,后序遍历
* 4.分层遍历二叉树(按层次从上往下,从左往右)
* 5.求二叉树第K层的节点个数
* 6.求二叉树中叶子节点的个数
* 7. 判断两棵二叉树是否结构相同
*/
import java.util.LinkedList;
import java.util.Queue; class TreeNode{
int key=0;
String data=null;
boolean isVisited=false; TreeNode leftChild=null;
TreeNode rightChild=null; public TreeNode(int key,String data) {
this.key=key;
this.data=data;
this.isVisited=false;
this.leftChild=null;
this.rightChild=null;
}
} public class BinaryTree { TreeNode root=null; public BinaryTree() {
root=new TreeNode(1, "A");
} //创建二叉树bt,树由节点构成
public void createBinTree(TreeNode root) {
TreeNode newNodeB=new TreeNode(2, "B");
TreeNode newNodeC=new TreeNode(3, "C");
TreeNode newNodeD=new TreeNode(4, "D");
TreeNode newNodeE=new TreeNode(5, "E");
TreeNode newNodeF=new TreeNode(6, "F"); root.leftChild=newNodeB;
root.rightChild=newNodeC;
root.leftChild.leftChild=newNodeD;
root.leftChild.rightChild=newNodeE;
root.rightChild.rightChild=newNodeF;
} //创建二叉树bt2,树由结点构成
public void createBinTree2(TreeNode root){
TreeNode newNodeB = new TreeNode(2,"B");
TreeNode newNodeC = new TreeNode(3,"C");
TreeNode newNodeD = new TreeNode(4,"D");
TreeNode newNodeE = new TreeNode(5,"E");
//填充它
root.leftChild = newNodeB;
root.rightChild = newNodeC;
root.leftChild.leftChild = newNodeD;
root.leftChild.rightChild = newNodeE;
} //访问节点,输出节点,便于我们查看效果
public void visitNode(TreeNode node) {
System.out.println(node.data+" ");
} //1.获取节点数
//递归解法:
//(1)如果二叉树为空,节点个数为0
//(2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1
public int size() {
return size(root);
} //通过递归求size
public int size(TreeNode subtree) {
if (subtree==null) {
return 0;
}else {
return 1+size(subtree.leftChild)+size(subtree.rightChild);
}
} //2.求深度
//递归解法:
//(1)如果二叉树为空,二叉树的深度为0
//(2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1
public int getDepth(TreeNode root) {
if (root==null) {
return 0;
}else {
int depthLeft=getDepth(root.leftChild);
int depthRight=getDepth(root.rightChild);
return depthLeft>depthRight?(depthLeft+1):(depthRight+1);
}
} //3. 前序遍历,中序遍历,后序遍历
//a.前序遍历
//前序遍历递归解法:
//(1)如果二叉树为空,空操作
//(2)如果二叉树不为空,访问根节点,前序遍历左子树,前序遍历右子树
public void preOrderTraverse(TreeNode root) {
if (root!=null) {
visitNode(root);
preOrderTraverse(root.leftChild);
preOrderTraverse(root.rightChild);
}
} //b.中序遍历
//中序遍历递归解法
//(1)如果二叉树为空,空操作。
//(2)如果二叉树不为空,中序遍历左子树,访问根节点,中序遍历右子树 public void inOrderTraverse(TreeNode root) {
if (root!=null) {
inOrderTraverse(root.leftChild);
visitNode(root);
inOrderTraverse(root.rightChild);
}
} //c.后序遍历
//后序遍历递归解法
//(1)如果二叉树为空,空操作。
//(2)如果二叉树不p为空,后序遍历左子树,后序遍历右子树,访问根节点,
public void postOrderTraverse(TreeNode root) {
if (root!=null) {
postOrderTraverse(root.leftChild);
postOrderTraverse(root.rightChild);
visitNode(root);
}
} //4.分层遍历二叉树(按层次从上往下,从左往右)
//相当于广度优先搜索,使用队列实现。队列初始化,将根节点压入队列。
//当队列不为空,进行如下操作:弹出一个节点,访问,若左子节点或右子节点不为空,将其压入队列。
public void levelTraverse(TreeNode root) {
if (root==null) {
return;
}
Queue<TreeNode> queue=new LinkedList<>();
//让根节点入队(队列:先进先出)
queue.offer(root);
while (!queue.isEmpty()) {
//让元素出队
TreeNode node=queue.poll();
//访问它 这里就是用visit方法输出看效果~~
visitNode(node);
if (node.leftChild!=null) {
queue.offer(node.leftChild);
}
if (node.rightChild!=null) {
queue.offer(node.rightChild);
}
}
return;
} //5.求二叉树第K层的节点个数
//递归解法:
//(1)如果二叉树为空或者k<1返回0
//(2)如果二叉树不为空并且k==1,返回1
//(3)如果二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树k-1层节点个数之和
public int getNodeNumKthLevel(TreeNode root,int k) {
if (root==null||k<1) {
return 0;
}else if (k==1) {
return 1;
}else {
int leftNum=getNodeNumKthLevel(root.leftChild, k-1);
int rightNum=getNodeNumKthLevel(root.rightChild, k-1);
return leftNum+rightNum;
}
} //6.求二叉树中叶子节点的个数
// 递归解法:
//(1)如果二叉树为空,返回0
//(2)如果二叉树不为空且左右子树为空,返回1
//(3)如果二叉树不为空,且左右子树不同时为空,返回左子树中叶子节点个数加上右子树中叶子节点个数
public int getLeafNodeNum(TreeNode root) {
if (root==null) {
return 0;
}else if (root.leftChild==null&&root.rightChild==null) {
return 1;
}else {
int leftNum=getLeafNodeNum(root.leftChild);
int rightNum=getLeafNodeNum(root.rightChild);
return leftNum+rightNum;
}
} //7. 判断两棵二叉树是否结构相同
//不考虑数据内容。结构相同意味着对应的左子树和对应的右子树都结构相同。
//递归解法:
//(1)如果两棵二叉树都为空,返回真
//(2)如果两棵二叉树一棵为空,另一棵不为空,返回假
//(3)如果两棵二叉树都不为空,如果对应的左子树和右子树都同构返回真,其他返回假
public boolean StructureCmp(TreeNode root1,TreeNode root2) {
if (root1==null&&root2==null) {
return true;
}else if (root1==null||root2==null) {
return false;
}else {
boolean leftResult=StructureCmp(root1.leftChild, root2.leftChild);
boolean rightResult=StructureCmp(root1.rightChild, root2.rightChild);
return leftResult&&rightResult;
}
}
}

测试类:

 package com.myutil.tree1;

 public class Main {
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
BinaryTree bt2 = new BinaryTree();
/*
由初始化的时候可知:我创建了一个这样的树,供查看写的方法是否正确
这棵树起名为bt: 这棵树起名为bt2 供比较
A A
/ \ / \
B C B C
/\ \ /\
D E F D E
*/
bt.createBinTree(bt.root);
bt2.createBinTree2(bt2.root); //1.看结点数
System.out.println("1.树的结点个数为:" + bt.size(bt.root));
//2.看深度
System.out.println("2.树的深度为:"+bt.getDepth(bt.root));
//3. 前序遍历,中序遍历,后序遍历
System.out.print("3-1.先序遍历:");
bt.preOrderTraverse(bt.root);
System.out.println(); System.out.print("3-2.中序遍历:");
bt.inOrderTraverse(bt.root);
System.out.println(); System.out.print("3-3.后序遍历:");
bt.postOrderTraverse(bt.root);
System.out.println(); //4.将二叉树用层次遍历
System.out.print("4.二叉树层次遍历:");
bt.levelTraverse(bt.root);
System.out.println(); //5.二叉树K层有多少个结点:由上图绘制可知:0层没有,1层有一个根节点,第二层有俩,第三次有仨
System.out.println("5.二叉树K层结点个数:");
System.out.println(" 当K=0时有"+bt.getNodeNumKthLevel(bt.root,0)+"个结点");
System.out.println(" 当K=1时有"+bt.getNodeNumKthLevel(bt.root,1)+"个结点");
System.out.println(" 当K=2时有"+bt.getNodeNumKthLevel(bt.root,2)+"个结点");
System.out.println(" 当K=3时有"+bt.getNodeNumKthLevel(bt.root,3)+"个结点"); //6.求二叉树中叶子节点的个数
System.out.print("6.二叉树叶子节点个数:");
System.out.println(bt.getLeafNodeNum(bt.root)); //7.比较两个二叉树相不相同
System.out.println("7.测试两树结构是否相同:");
System.out.println(" b1和b1:"+bt.StructureCmp(bt.root,bt.root));
System.out.println(" b1和b2:"+bt.StructureCmp(bt.root,bt2.root));
}
}

相关连接:轻松搞定面试中的二叉树题目

     java数据结构与算法之树基本概念及二叉树(BinaryTree)的设计与实现

数据结构Java实现04---树及其相关操作的更多相关文章

  1. 乐字节Java反射之四:反射相关操作

    大家好,乐字节小乐继续为Java初学者讲述Java基础知识.上次说到乐字节Java反射之三:方法.数组.类加载器,这次是Java反射之四:反射相关操作 1.操作属性 //1.获取Class对象 Cla ...

  2. Java编程之Date的相关操作

    一:讲字符串的时间格式数据转换成时间对象 //将字符串的时间数据,转换成时间 String dateString="2007-12-12"; DateFormat date=new ...

  3. 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树

    另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...

  4. java数据结构-非线性结构之树

    一.树状图 树状图是一种数据结构,它是由n(n>=1)个有限节点组成的具有层次关系的集合.因其结构看起来想个倒挂的树,即根朝上,叶子在下,故被称为"树". 特点: 1. 每个 ...

  5. 利用JAVA API远程进行HDFS的相关操作

    学习HDFS有一段时间了,现在把自己总结的HDFS的相关操作代码展示给大家. 主要有HDFS的增删改查,文件的追加,windows本地文件的上传,hdfs文件的下载,文件重命名,创建目录,文件是否存在 ...

  6. java 的Date 日期相关操作

    String 与 Date互转(1)基于SimpleDateFormat实现: package com.bky.df; import java.text.ParseException; import ...

  7. java文件夹相关操作 演示样例代码

    java文件夹相关操作 演示样例代码 package org.rui.io; import java.io.File; import java.io.FilenameFilter; import ja ...

  8. java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4

    java 线程  原子类相关操作演示样例 package org.rui.thread.volatiles; import java.util.Timer; import java.util.Time ...

  9. Java IO_001.File类--文件或文件夹相关操作

    Java IO之File对象常用操作 File类:用于文件或文件夹或网址相关联的操作.可以关联或不关联文件(即关联不存在的文件).构造函数有: public File(String pathname) ...

随机推荐

  1. 贴一段shell代码

    好久没用shell了,呵呵,这个是当counter < 1000的时候,往tmp.sql里填这两个字符串,生成假数据. #!/usr/bin/env bash COUNTER= ]; do ec ...

  2. jsp配置项目时出错Deployment failure on Tomcat 6.x. Could not copy all resources to

    转自:http://www.2cto.com/kf/201201/116853.html 今天在网上部署项目的时候出现在了问题 tomcat一直部署不上 网上查了一下 原因记下来供大家查看 Deplo ...

  3. 成功安装mysql后,为何服务管理器里找不到MYSQL服务名

    1.打开cmd,切换到mysql的bin目录下 2. D:\Program Files\MySQL5.1\bin>mysqld.exe -installService successfully ...

  4. 在chrome浏览器和在IE浏览器中显示的页面样式不一样的解决办法

    在IE浏览器中添加 一行代码即可:<meta http-equiv="X-UA-Compatible" content="IE=edge" /> 位 ...

  5. 自定义圆的半径attr.xml

    <?xml version="1.0" encoding="utf-8"?><resources>    <declare-sty ...

  6. hadoop-spark-hive-hbase配置相关说明

    1. zookeeper 配置 cp app/ochadoop-och3.0.0-SNAPSHOT/zookeeper-3.4.5-cdh5.0.0-beta-2-och3.0.0-SNAPSHOT/ ...

  7. 开发的时候,一定要及时控制CPU使用率以及使用内存大小等三个问题(一个星期检查一次)

    一直专注于功能的开发,没注意CPU和内存.昨天无意中发现两个问题: 1. 程序启动后,什么都没干,CPU就50%了(单核).现在想找原因降低使用率,感觉无从下手,要是平时就注意这个问题就好了. 2. ...

  8. MySQL中Left Join和Right Join的理解

    虽然之前一直见过两个Join,对于其具体的含义也在参考书上读过,但是一直没有记住.现在换一种方式进行学习,改为实验方式理解. Left Join 测试表: 表结构很简单,test包括两个int字段,t ...

  9. How to Install LibreOffice 6.0 on Ubuntu 16.04 LTS +

    1. Add the LibreOffice 6.0 PPA The LibreOffice Fresh PPA is maintained by LibreOffice. It provides l ...

  10. Oracle之ora-01031 insufficient privileges

              解决ora-01031insufficient privileges错误 解决system用户不能登录的问题 alter user system account unlock id ...