概念:二叉树是每个结点最多有两个子树的树结构
一、为什么要使用二叉树?
因为它通常结合了另外两种数据结构的优点:一种是有序数组,另一种是链表
。在树中查找数据项的速度和在有序数组中查找一样快,并且插入数据项和删除数据项的速度也和链表一样
二、java实现二叉树(新增、删除、查询、遍历)
package datasStructure;
import lombok.Data;
/**
* @program: practise-model
* @description: 二叉树
* @author: lbw
* @create: 2022-04-07 17:53
**/
public class binaryNumber {
//根节点
Node root;
@Data
class Node {
private int value;
private Node left;
private Node right;
Node() {
}
Node(int value) {
this.value = value;
}
}
向二叉树中插入节点
public Node insertNode(int key) {
Node node = new Node(key);
if (root == null) {
root=node;
return node;
}
Node current = root;
Node parent = null;
//循环查找需要插入的节点prev
//当p为null时候退出循环,此时prev为要插入key的上级节点
while (current != null) {
parent = current;
if (key < current.getValue()) {
current = current.getLeft();
} else {
current = current.getRight();
}
}
if (key < parent.getValue()) {
parent.left = node;
} else {
parent.right = node;
}
return node;
}
删除二叉树节点,其中分为三种情况
1.该节点是叶节点,只要把父节点对应的子节点改成null即可
2.节点有一个子节点,删除该节点,只需要将需要删除的节点的唯一一个
子节点连接到需要删除的节点的父亲节点之上即可
3.有两个子节点,需要找到该删除节点的中序后继节点来替换当前删除的节点
其中第三种情况:
public boolean deleteNode(int value) {
//引用当前节点,从根节点开始
Node current = root;
//应用当前节点的父节点
Node parent = root;
//是否为左节点
boolean isleft = true;
while (current.value != value) {
parent = current;
//进行比较,比较查找值和当前节点的大小
if (current.value > value) {
current = current.left;
isleft = true;
} else {
current = current.right;
isleft = false;
}
if (current == null) {
return false;
}
}
//1.该节点是叶节点,只要把父节点对应的子节点改成null即可
if (current.left == null && current.right == null) {
if (current == root) {
root = null;
} else if (isleft) {//如果它是父节点的左子节点
parent.left = null;
} else {
parent.right = null;
}
return true;
}
//2.节点有一个子节点,删除该节点,只需要将需要删除的节点的唯一一个
// 子节点连接到需要删除的节点的父亲节点之上即可
if (current.right == null) {
if (current == root) {
root = current.left;
} else if (isleft) {
parent.left = current.left;
} else {
parent.right = current.left;
}
return true;
}
if (current.left == null) {
if (current == root) {
root = current.right;
} else if (isleft) {
parent.left = current.right;
} else {
parent.right = current.right;
}
return true;
}
//3.有两个子节点,需要找到该删除节点的中序后继节点来替换当前删除的节点
Node successor = getSuccessor(current);
System.out.println("successor:"+successor);
if (current == root) {
root = successor;
} else if (isleft) {
parent.left = successor;
} else {
parent.right = successor;
}
successor.left = current.left;
return true;
}
/**
* 这是寻找中序后继节点方法
* 寻找中序后继节点.先找出待删除节点右子节点,然后一直往左边找到最小值,此节点就是中序后继节点
*
* @param delNode
* @return
*/
public Node getSuccessor(Node delNode) {
Node successor = delNode;
Node successorParent = delNode;
Node current = delNode.right;
while (current != null) {
successorParent = successor;
successor = current;
current = current.left;
}
if (successor != delNode.right) {
//将后继节点的父节点的左子节点值设置为后继的右子节点
//后继节点的右子节点放置到后继节点父节点的左子节点
successorParent.left = successor.right;
//将删除的节点的整个右子树挂载到中继节点的右子树上
//即把要删除的右子节点放置到中序后继节点右子节点
successor.right = delNode.right;
}
return successor;
}
遍历二叉树上的节点
/**
* 中序遍历
*/
public void inOrder(Node localNode) {
if (localNode != null) {
//中序遍历左子树
inOrder(localNode.left);
//访问根节点
System.out.println(localNode.value + "," + localNode.value);
//中序遍历右子树
inOrder(localNode.right);
}
}
//这是查找node
查找二叉树上的节点
public Node find(int key) {
Node current = root;
while (current != null) {
if (current.value > key) {
//当前值比查找值大 则继续遍历左子树
current = current.left;
} else if (current.value < key) {
//当前值小于查找值 则继续遍历右子树
current = current.right;
} else {
//查找到 返回
return current;
}
}
return null;
}
public static void main(String[] args) {
binaryNumber binaryNumber=new binaryNumber();
binaryNumber.insertNode(20);
binaryNumber.insertNode(19);
binaryNumber.insertNode(21);
binaryNumber.insertNode(22);
binaryNumber.insertNode(10);
binaryNumber.insertNode(9);
binaryNumber.insertNode(15);
binaryNumber.insertNode(13);
binaryNumber.insertNode(11);
Node node=binaryNumber.find(20);
binaryNumber.inOrder(node);
System.out.println("========================");
Node node1=binaryNumber.find(21);
binaryNumber.inOrder(node1);
System.out.println("========================");
binaryNumber.deleteNode(10);
Node node2=binaryNumber.find(20);
binaryNumber.inOrder(node2);
}
}
结果: