一、定义
左子树的节点值均小于根节点
右子树的值均大于根节点
二、基本操作
1 创建节点类
package tree;
public class Node {
private int data;
private Node leftChild;
private Node rightChild;
public Node() {}
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeftChild() {
return leftChild;
}
public void setLeftChild(Node leftChild) {
this.leftChild = leftChild;
}
public Node getRightChild() {
return rightChild;
}
public void setRightChild(Node rightChild) {
this.rightChild = rightChild;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
", leftChild=" + leftChild +
", rightChild=" + rightChild +
'}';
}
}
2 二叉树的查找操作
- 从根节点开始查找
* 只要当前节点不为空如果要查找的数据大于当前节点,当前节点等于当前节点的右孩子;
* 如果要查找的数据等于当前节点,返回当前节点
* 如果要查找的数据小于当前节点,当前节点等于当前节点的左孩子
三、完整代码
package tree;
/**
* 二叉树基本的类结构
*/
public class BinaryTree {
private Node root;
public BinaryTree() {
root = null;
}
//查找某个节点
public Node find(int data) {
Node current = root;
while (current != null) { //当前节点不是null的时候,才继续循环
if (data < current.getData()) {
current = current.getLeftChild();
} else if (data > current.getData()) {
current = current.getRightChild();
} else {
return current;
}
}
//循环完了,current==null说明树里根本没有我们要找的节点
return null;
}
//插入节点
public boolean insert(int data) {
Node newNode = new Node(data);
if (root == null) {
root = newNode;
return true;
} else {
Node current = root;
Node parentNode = null;
while (current != null) {
parentNode = current;
if (data < current.getData()) {
current = current.getLeftChild();
if (current == null) {
parentNode.setLeftChild(newNode);
return true;
}
} else {
current = current.getRightChild();
if (current == null) {
parentNode.setRightChild(newNode);
return true;
}
}
}
}
return false; //插入失败
}
//遍历节点
//中序遍历
public void midOrder(Node current) {
//先左
if (current == null) {
return;
} else {
midOrder(current.getLeftChild());
System.out.println(current.getData());
midOrder(current.getRightChild());
}
}
//前序遍历
public void preOrder(Node current) {
if (current == null) {
return;
} else {
System.out.println(current.getData());
preOrder(current.getLeftChild());
preOrder(current.getRightChild());
}
}
//后序遍历
public void afterOrder(Node current) {
if (current == null) {
return;
} else {
afterOrder(current.getLeftChild());
afterOrder(current.getRightChild());
System.out.println(current.getData());
}
}
//查找最大值和最小值
public Node getMaxNode() {
Node current = root;
Node maxNode = current;
while (current != null) {
maxNode = current;
current = current.getRightChild();
}
return maxNode;
}
public Node getMinNode() {
Node current = root;
Node minNode = current;
while (current != null) {
minNode = current;
current = current.getLeftChild();
}
return minNode;
}
//删除节点
public boolean delete(int data) {
//找到要删除的节点
Node current = root;
Node parent = null;
boolean isLeftChild = false; //判断当前节点是其父节点的左孩子还是右孩子
while (current.getData() != data) {
parent = current;
if (data < current.getData()) {
current = current.getLeftChild();
isLeftChild = true;
} else {
current = current.getRightChild();
isLeftChild = false;
}
if (current == null) { //树里根本没有要删除的节点
return false; //结束方法,循环结束
}
}
//正常循环结束,找到了要删除的节点
//删除找到的节点
if (current.getLeftChild() == null && current.getRightChild() == null) { //要删除节点是叶子节点
if (current == root) {
root = null;
} else {
if (isLeftChild) { //当前节点是父节点的左孩子
parent.setLeftChild(null);
} else {
parent.setRightChild(null);
}
}
return true;
} else if (current.getLeftChild() != null && current.getRightChild() == null) {
if (current == root) {
root = current.getLeftChild();
} else {
if (isLeftChild) {
parent.setLeftChild(current.getLeftChild());
} else {
parent.setRightChild(current.getLeftChild());
}
}
return true;
} else if (current.getLeftChild() == null && current.getRightChild() != null) {
if (current == root) {
root = current.getRightChild();
} else {
if (isLeftChild) {
parent.setLeftChild(current.getRightChild());
} else {
parent.setRightChild(current.getRightChild());
}
}
return true;
} else { //要删除的节点有两个子节点的情况
//先找到要被删除的节点的右子树中的最小节点
Node replaceNode = getReplaceNode(current);
if (current == root) {
root = replaceNode;
} else {
if (isLeftChild) {
parent.setLeftChild(replaceNode);
} else {
parent.setRightChild(replaceNode);
}
}
replaceNode.setLeftChild(current.getLeftChild());
return true;
}
}
public Node getReplaceNode(Node delNode) {
Node replaceNode = delNode;
Node replaceNodeParent = delNode;
Node grnCurrent = delNode.getRightChild();
while (grnCurrent != null) {
replaceNodeParent = replaceNode;
replaceNode = grnCurrent;
grnCurrent = grnCurrent.getLeftChild();
}
if (replaceNode != delNode.getRightChild()) {
replaceNodeParent.setLeftChild(replaceNode.getRightChild());
replaceNode.setRightChild(delNode.getRightChild());
}
return replaceNode; //我们要找的右子树中的最小节点
}
}
四、测试
package tree;
public class BinaryTreeTest {
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.insert(40);
bt.insert(36);
bt.insert(37);
bt.insert(85);
bt.insert(49);
bt.insert(88);
Node root = bt.find(40);
bt.midOrder(root);
System.out.println();
bt.delete(85);
bt.midOrder(root);
}
}