文章目录
一、基本含义
1.1 树结构
树结构:树是一种非线性的数据结构,相对于线性的数据结构(链表、数组)而言,树的平均运行时间更短(往往与树相关的排序时间复杂度都不会高)。
根节点:树根。
叶子:没有子节点的节点。
深度:代数。
注意:
1、树是非线性的,计算机的内存是线性存储的。
2、在编程的世界中,一般把树“倒”过来看。
1.2 定义树
注意:一棵树至少会有一个节点(根节点)。
树由节点组成。
定义树的顺序:定义节点->节点连接起来就成了树。
定义节点:一个数据、两个指针(如果有节点就指向节点、没有节点就指向null)。
1.3 二叉树
二叉树含义:
1、是最简单又经常用的树结构。
2、一个节点的子节点个数不能超过2。
二叉查找树(binary search tree):一种特殊的二叉树。
二叉查找树定义:当前根节点的左边全部比根节点小,当前根节点的右边全部比根节点大。
二、创建二叉树
原理:
1、树是由若干个节点组成,节点连接起来就成了树。
2、节点由一个数据、两个指针组成。
3、创建树实际上就是创建节点,然后连接节点。
2.1 静态创建
第一步:创建节点类。
TreeNode.java
public class TreeNode {
private TreeNode leftNode; // 左节点
private TreeNode rightNode;// 右节点
private int value;// 数据
public TreeNode(int value){
this.value = value;
}
}
第二步:创建节点
App.java
public static void main ( String [] args) {
//根节点-->10
TreeNode treeNode1 = new TreeNode (10);
//左孩子-->9
TreeNode treeNode2 = new TreeNode (9);
//右孩子-->20
TreeNode treeNode3 = new TreeNode(20);
//20的左孩子-->15
TreeNode treeNode4 = new TreeNode(15);
//20的右孩子-->35
TreeNode treeNode5 = new TreeNode(35);
}
第三步:连接节点
App.java
public static void main ( String [] args) {
//根节点的左右孩子
treeNode1.setLeftNode(treeNode2);
treeNode1.setRightNode(treeNode3);
//20节点的左右孩子
treeNode3.setLeftNode(treeNode4);
treeNode3.setRightNode(treeNode5);
}
2.2 动态创建
注意:一般创建的是二叉查找树,即无论任何一颗子树,左边都比根要小,右边比根要大。
步骤:
1、创建节点类。
2、判断是否有根节点
——若无,则创建节点(当前值),直接作为根节点。
——若有,则当前值与根节点值比较。
3、对比当前值与根节点值。
——若大,则进入右节点。
——若小,则进入左节点。
4、判断左(右)节点是否有值。
——若无,则创建节点(当前值),作为左(右)节点。
——若有,则把左(右)节点作为根节点,重复3、4步骤。
TreeNode.java
public class TreeNode {
private TreeNode treeRoot; // 父节点。
private TreeNode leftNode; // 左子节点
private TreeNode rightNode;// 右子节点
private int value;// 当前节点数据。
// setter/getter方法。
public TreeNode(int value){
this.value = value;
}
}
App.java
public static void createTree(TreeNode treeRoot,int value){
// 第一步:获取当前节点的父节点。
TreeNode tempRoot = treeRoot.getTreeRoot();
// 第二步:判断父节点是否有值。
if(tempRoot == null){
// 父节点无值,则当前节点设为父节点。
TreeNode treeNode = new TreeNode(value);
treeRoot.setTreeRoot(treeNode);
}else{
// 父节点有值,则继续向下寻找合适位置。
while(tempRoot != null){
// 当前值是否大于根节点值。
if(value > tempRoot.getVlaue()){
//右边没有树根,那就直接插入
if(tempRoot.getRightNode() == null){
tempRoot.setRightNode(new TreeNode(value));
return;
}else{
//如果右边有树根,到右边的树根去
tempRoot = tempRoot.getRightNode();
}
}else{
//左边没有树根,那就直接插入
if(tempRoot.getLeftNode() == null){
tempRoot.setLeftNode(new TreeNode(value));
return;
}else{
//如果左边有树根,到右边的树根去
tempRoot = tempRoot.getLeftNode();
}
}
}
}
}
// 测试。
public static void main(string[] arg){
int[] arr = {2,3,1,4,5};
TreeNode treeNode = new TreeNode();
for(int value: arr){
createTree(treeNode,value);
}
preTraverseBtree(treeNode.getTreeRoot());
}
三、遍历二叉树
先序(根->左->右),中序(左->根->右),后序(左->右->根)。如果访问有孩子的节点,先处理孩子的,随后返回。
3.1 先序遍历
含义:先访问根节点,然后访问左节点,最后访问右节点(根->左->右)。
示例:10->9->20->15->35
public static void preTraverseBtree(TreeNode rootTreeNode){
if(rootTreeNode != null){
System.out.println(rootTreeNode.getValue);
preTraverseBtree(rootTreeNode.getLeftNode());
preTraverseBtree(rootTreeNode.getRightNode());
}
}
3.2 中序遍历
含义:先访问左节点,然后访问根节点,最后访问右节点(左->根->右)。
示例:9->10->15->20->35
public static void inTraverseBtree(TreeNode rootTreeNode){
if(rootTreeNode != null){
preTraverseBtree(rootTreeNode.getLeftNode());
System.out.println(rootTreeNode.getValue);
preTraverseBtree(rootTreeNode.getRightNode());
}
}
3.3 后序遍历
含义:先访问左节点,然后访问右节点,最后访问根节点(左->右->根)。
示例:9->15->35->20->10
public static void inTraverseBtree(TreeNode rootTreeNode){
if(rootTreeNode != null){
preTraverseBtree(rootTreeNode.getLeftNode());
preTraverseBtree(rootTreeNode.getRightNode());
System.out.println(rootTreeNode.getValue);
}
}
四、查询二叉查找树相关
4.1 查询树的深度
思路:
1、当左(右)节点再无子节点时,返回值为0。
2、以当前节点为末代,向上寻找父节点,直到根节点,每找到一个父节点,返回值+1。
3、左边和右边的返回值比,谁大就返回谁。
public static int getHeight(TreeNode treeNode){
if(treeNode == null){
return 0; // 初始值。
}else{
int left = getHeight(treeNode.getLeftNode());
int right = getHeight(treeNode.getRightNode());
int max = right > left ? right:left;
return max + 1;
}
}
4.2 查询树的最大值
思路:
1、左边找最大值->递归。
2、右边找最大值->递归。
3、选取左最大、右最大、根节点三者中的最大值。
public static int getMax(TreeNode treeNode){
if(treeNode == null){
return -1;
}else{
int left = getMax(treeNode.getLeftNode());
int right = getMax(treeNode.getRightNode());
int currenRootValue = treeNode.getValue();
int max = right > left ? right:left;
max = max > currenRootValue ? max : currenRootValue;
return max;
}
}