简介
二叉树的相关概念,如,树高度,节点层数,节点度数,路径,叶节点,分支节点,根节点,父节点,左节点,右节点,兄弟节点,祖先节点,子孙节点,左子树,右子树等基本概念,不再赘述。
本文主要讲解二叉树的创建,删除,以及四种遍历方式。
二叉树
二叉树是一个递归的数据结构,每个节点最多有两个子节点。
通常二叉树是二分查找树,每个节点它的值大于或者等于在它左子树节点上的值,小于或者等于在它右子树节点上的值,如下图
二叉树的遍历方式有4种:
- 前序遍历:root -> left -> right
- 中序遍历:left -> root -> right
- 后序遍历:left ->right -> root
- 层序遍历:按照层次遍历
上图二叉树4种遍历如下:
前序遍历:6->4->3->5->8->7->9
中序遍历:3->4->5->6->7->8->9
后续遍历:3->5->4->7->9->8->6
层次遍历:6->4->8->3->5->7->9
创建节点
为了实现二叉树,我们使用一个Node类来表示节点,节点存储int类型的值,还有对子节点的引用。
public class Node {
int data;
Node left;
Node right;
public Node(){}
public Node(int data){
this.data = data;
this.left = null;
this.right = null;
}
}
创建二叉树
写一个二叉树类,然后添加树的root节点
public class BinaryTree {
Node root;
}
添加元素
我们第一次添加元素的时候,root为空,第一个元素就作为根节点,继续添加元素则遵循以下原则
- 如果新节点小于当前的值,我们将会进入左子树
- 如果新节点大于当前的节点。我们将会进入右子树
- 当当前的节点是null时,我们已经到达叶子节点,我们可以添加新节点到这个位置。
我们将会创建递归方法做添加节点操作
代码如下:
public void addNode(int value) {
root = addNode(root, value);
}
private Node addNode(Node current, int value) {
if (current == null) {
return new Node(value);
}
if (value < current.data) {
current.left = addNode(current.left, value);
} else if (value > current.data) {
current.right = addNode(current.right, value);
} else {
return current;
}
return current;
}
查找节点
/**
* 查找一个节点
*/
public boolean containNode(int value) {
return containNode(root, value);
}
private boolean containNode(Node current, int value) {
if (current == null) {
return false;
}
if (value == current.data) {
return true;
}
return value < current.data ? containNode(current.left, value) : containNode(current.right, value);
}
树的深度
/**
* 树的深度
* 左子树或右子树最大深度+1就是树的深度
* @return
*/
public int deepness(){
return deepness(root);
}
private int deepness(Node root){
if(root==null){
return -1;
}
int lmax = 0; //左子树的深度
int rmax = 0; //右子树的深度
if(root.left!=null){
lmax = deepness(root.left);
}
if(root.right!=null){
rmax = deepness(root.right);
}
return lmax > rmax ? lmax+1 : rmax+1;
}
删除节点
/**
* 删除一个节点
*/
public void deleteNode(int value){
deleteNode(root,value);
}
private Node deleteNode(Node current, int value) {
if (current == null) {
return null;
}
if (value == current.data) {
if (current.left == null && current.right == null) {
return null;
}
if (current.left == null) {
return current.right;
}
if (current.right == null) {
return current.left;
}
int smallestValue = findSmallestValue(current.right);
current.data = smallestValue;
current.right = deleteNode(current.right, smallestValue);
return current;
}
if (value < current.data) {
current.left = deleteNode(current.left, value);
return current;
}
current.right = deleteNode(current.right, value);
return current;
}
private int findSmallestValue(Node root) {
return root.left == null ? root.data : findSmallestValue(root.right);
}
遍历树
/**
* 中序遍历
*/
public void InOrderTraverse() {
InOrderTraverse(root);
}
public void InOrderTraverse(Node root) {
if (root != null) {
InOrderTraverse(root.left);
System.out.print(root.data+" ");
InOrderTraverse(root.right);
}
}
/**
*前序遍历
*/
public void PreOrderTraverse() {
PreOrderTraverse(root);
}
private void PreOrderTraverse(Node root) {
if (root != null) {
System.out.print(root.data+" ");
PreOrderTraverse(root.left);
PreOrderTraverse(root.right);
}
}
/**
*后序遍历
*/
public void PostOrderTraverse() {
PostOrderTraverse(root);
}
private void PostOrderTraverse(Node root) {
if (root != null) {
PostOrderTraverse(root.left);
PostOrderTraverse(root.right);
System.out.print(root.data+" ");
}
}
/**
* 层次遍历
*/
public void LevelOrderTraverse() {
LevelOrderTraverse(root);
}
private void LevelOrderTraverse(Node root) {
if (root == null) {
return;
}
Queue<Node> nodes = new LinkedList<Node>();
nodes.add(root);
while(!nodes.isEmpty()) {
Node node = nodes.remove();
System.out.print(node.data+" ");
if (node.left != null) {
nodes.add(node.left);
}
if (node.right != null) {
nodes.add(node.right);
}
}
}
创建测试类
/**
* @Author zsn
* @Date 2021/6/24 14:14
*/
public class BinaryTreeTest {
public static void main(String[] args) {
BinaryTree tree = new BinaryTree();
tree.addNode(6);
tree.addNode(4);
tree.addNode(8);
tree.addNode(3);
tree.addNode(5);
tree.addNode(7);
tree.addNode(9);
System.out.println("1是否存在:"+tree.containNode(1));
System.out.println("3是否存在:"+tree.containNode(3));
System.out.println("前序遍历:");
tree.PreOrderTraverse();
System.out.println();
System.out.println("中序遍历:");
tree.InOrderTraverse();
System.out.println();
System.out.println("后序遍历:");
tree.PostOrderTraverse();
System.out.println();
System.out.println("层次遍历:");
tree.LevelOrderTraverse();
//删除元素
tree.deleteNode(9);
System.out.println();
System.out.println("删除后的层次遍历:");
tree.LevelOrderTraverse();
}
}
运行结果如下: