数据结构与算法-二叉树

一、基本含义

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;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值