概念
每个节点最多有两个的子节点的树,称为二叉树,二叉树是最基础的树,其他的算法树大多是在二叉树的前提下加以限制,或有特殊要求。
二叉树的相关术语:
-
节点:包含一个数据元素及若干指向子树分支的信息,一般一个节点所包含的属性有:节点数值,左节点,右节点
-
节点的度:一个节点拥有子树的数目称为节点的度,即一个节点有几个子分支,没有子节点度为0,仅有一个子节点度为1,以此类推
-
叶子节点:也称为终端节点,没有子树的节点或者度为零的节点
-
分支节点:也称为非终端节点,度不为零的节点称为非终端节点
-
树的度:树中所有节点的度的最大值
-
节点的层次:从根节点开始,假设根节点为第1层,根节点的子节点为第2层,依此类推,如果某一个节点位于第L层,则其子节点位于第L+1层
-
树的深度:也称为树的高度,树中所有节点的层次最大值称为树的深度
-
有序树:如果树中各棵子树的次序是有先后次序,则称该树为有序树
-
无序树:如果树中各棵子树的次序没有先后次序,则称该树为无序树
-
森林:由m(m≥0)棵互不相交的树构成一片森林。如果把一棵非空的树的根节点删除,则该树就变成了一片森林,森林中的树由原来根节点的各棵子树构成
二叉树的性质
-
n0 + n2 = n
-
n0 = n2 + 1
-
2* n2 + 1 = n
-
n2 = (n-1)/2
数字为节点的度
二叉树的创建
在java中创建一个二叉树分为两部分:节点和树
这里直接上代码
/**节点类**/
class TreeNode {
private int id;
private String name;
private TreeNode left;
private TreeNode right;
@Override
public String toString() {
return "TreeNode{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public TreeNode(int id, String name) {
this.id = id;
this.name = name;
}
public TreeNode() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TreeNode getLeft() {
return left;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public TreeNode getRight() {
return right;
}
public void setRight(TreeNode right) {
this.right = right;
}
}
/**树类**/
class BinaryTree{
private TreeNode root;
public void setRoot(TreeNode root) {
this.root = root;
}
}
有了这两个类,我们只需创建几个节点,将其中一个节点设置为树的根结点,并将其余的节点放在其左右节点即可
public class BinaryTreeDemo {
public static void main(String[] args) {
// 先创建二叉树的节点
BinaryTree binaryTree = new BinaryTree();
TreeNode root = new TreeNode(1,"嘉然");
TreeNode node2 = new TreeNode(2,"向晚");
TreeNode node3 = new TreeNode(3,"乃琳");
TreeNode node4 = new TreeNode(4,"贝拉");
TreeNode node5 = new TreeNode(5,"珈乐");
// 手动创建二叉树
binaryTree.setRoot(root);
root.setLeft(node3);
root.setRight(node2);
node2.setRight(node4);
node2.setLeft(node5);
}
}
此时我们就创建好了一个二叉树,如图
二叉树的遍历
二叉树的遍历有三种:先序遍历,中序遍历,后序遍历
-
先序遍历
-
遍历顺序为根、左、右,即先遍历一个树的根结点,在遍历其左子树,最后是右子树,遍历是一个递归的过程,直到遍历到没有左右子节点的叶子节点返回上一层
-
先序遍历输出上述二叉树的结果为:1、3、2、5、4
-
-
中序遍历
-
遍历顺序为左、根、右,即先遍历一个树的左子树,在遍历其根结点,最后是右子树,遍历是一个递归的过程,直到遍历到没有左右子节点的叶子节点返回上一层
-
中序遍历输出上述二叉树的结果为:3、1、5、2、4
-
-
后序遍历
-
遍历顺序为左、右、根,即先遍历一个树的左子树,在遍历其右子树,最后是根结点,遍历是一个递归的过程,直到遍历到没有左右子节点的叶子节点返回上一层
-
中序遍历输出上述二叉树的结果为:3、5、4、2、1
-
这里给出三种遍历打印和查找的代码
class TreeNode {
// 先序遍历(根 左 右)
public void preOrder() {
System.out.println(this);
if (this.left != null) {
this.left.preOrder();
}
if (this.right != null) {
this.right.preOrder();
}
}
// 中序遍历(左 根 右)
public void infixOrder() {
if (this.left != null) {
this.left.infixOrder();
}
System.out.println(this);
if (this.right != null) {
this.right.infixOrder();
}
}
// 后序遍历(左 右 根)
public void postOrder() {
if (this.left != null) {
this.left.postOrder();
}
if (this.right != null) {
this.right.postOrder();
}
System.out.println(this);
}
/**
* 先序查找
* @param id
* @return
*/
public TreeNode preFind(int id) {
TreeNode treeNode = null;
if (this.id == id) {
treeNode = this;
return treeNode;
}
if (this.left != null) {
treeNode = this.left.preFind(id);
}
if (this.right != null) {
treeNode = this.right.preFind(id);
}
return treeNode;
}
/**
* 中序查找
* @param id
* @return
*/
public TreeNode infixFind(int id) {
TreeNode treeNode = null;
if (this.left != null) {
treeNode = this.left.infixFind(id);
}
if (this.id == id) {
treeNode = this;
return treeNode;
}
if (this.right != null) {
treeNode = this.right.infixFind(id);
}
return treeNode;
}
/**
* 后序查找
* @param id
* @return
*/
public TreeNode postFind(int id) {
TreeNode treeNode = null;
if (this.left != null) {
treeNode = this.left.postFind(id);
}
if (this.right != null) {
treeNode = this.right.postFind(id);
}
if (this.id == id) {
treeNode = this;
return treeNode;
}
return treeNode;
}
}
class BinaryTree{
/**
* 先序查找
* @param id
* @return
*/
public TreeNode preFind(int id){
if (this.root == null){
System.out.println("二叉树为空");
return null;
}else {
return root.preFind(id);
}
}
/**
* 中需查找
* @param id
* @return
*/
public TreeNode infixFind(int id){
if (this.root == null){
System.out.println("二叉树为空");
return null;
}else {
return root.infixFind(id);
}
}
/**
* 后序查找
* @param id
* @return
*/
public TreeNode postFind(int id){
if (this.root == null){
System.out.println("二叉树为空");
return null;
}else {
return root.postFind(id);
}
}
// 先序遍历
public void preOrder(){
if (this.root != null) {
root.preOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
// 中序遍历
public void infixOrder(){
if (this.root != null){
root.infixOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
// 后序遍历
public void postOrder(){
if (this.root != null){
root.postOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
}