顺序二叉树就是每一个节点的左子节点都要比当前节点小,每一个节点的右子节点都要比当前节点大;
增加节点思路:判断待插入节点和当前节点的大小,如果待插入节点更大的话并且当前节点的右节点为空直接插到当前节点的右子节点上,否则当前节点的右子节点进行递归;如果待插入节点更小并且当前节点的左子节点为空直接插入,否则当前节点的左子节点进行递归。
查找节点的思路:根据顺序二叉树的特点进行查找,不需要像普通二叉树一样遍历;先和当前节点进行比较,如果相等直接返回,如果当前节点更大并且当前节点的左子节点为空直接返回null,否则递归当前节点的左子节点,如果当前节点更小并且当前节点的右子节点为空返回null,否则递归当前节点的右子节点;由于是单向递归因此都直接返回就好了
查找父节点和查找节点的思路是一样的;
删除节点:删除节点有三种情况:1、删除的节点是叶子节点则直接删除 2、删除的节点是只有一个子节点的非叶子节点(要判断待删除节点点也是只有一个子树),直接对应就好 3、删除的节点是有两个子树的节点,这时要么找到右子树中最小的、要么找到左子树中最大的,将这个找到的节点删掉之后,用它的值来替换待删除节点
代码如下:
package cn.java.study.review.tree;
/*二叉排序树*/
public class binarySortTree {
Node root;
void createTree(int[] arr) {
for (int i : arr) {
if (root == null) {
root = new Node(i);
} else {
createTree(i, root);
}
}
}
void remove(int id) {
if (root == null) {
System.out.println("root is null");
return;
}
root.remove(id);
}
void createTree(int i, Node n) {
Node node = new Node(i);
Node temp = root;
if (n.id > i) {
if (n.left == null) {
n.left = node;
} else {
createTree(i, n.left);
}
} else {
if (n.right == null) {
n.right = node;
} else {
createTree(i, n.right);
}
}
}
void infixTraverse(Node node) {
if (node.left != null) {
infixTraverse(node.left);
}
System.out.print(node.id + "--");
if (node.right != null) {
infixTraverse(node.right);
}
}
class Node {
int id;
Node left;
Node right;
Node(int id) {
this.id = id;
}
Node findParentNode(int id) {
if ((this.left != null && this.left.id == id) || (this.right != null && this.right.id == id)) {
return this;
}
if (this.id > id && this.left != null) {
return this.left.findParentNode(id);
} else if (this.id < id && this.right != null) {
return this.right.findParentNode(id);
}
return null;
}
Node findNode(int id) {
if (this.id == id) {
return this;
}
if (this.id > id && this.left != null) {
return this.left.findNode(id);
} else if (this.id < id && this.right != null) {
return this.right.findNode(id);
}
return null;
}
//删除节点1、叶子节点 2、非叶子节点只有一个子树 3、非叶子节点且有两个子树
void remove(int id) {
//根节且没有子树
if (root.id == id && root.left == null && root.right == null) {
root = null;
return;
}
Node parent = this.findParentNode(id);
Node self = this.findNode(id);
//如果是叶子节点
if (self.left == null && self.right == null) {
if (parent.left == self) {
parent.left = null;
}
if (parent.right == self) {
parent.right = null;
}
}
//如果只有右子树,要考虑为根节点
if (self.left == null && self.right != null) {
if (parent == null) {
root = self.right;
} else {
if (parent.left == self) {
parent.left = self.right;
}
if (parent.right == self) {
parent.right = self.right;
}
}
}
//如果只有左子树,要考虑为根节点
if (self.right == null && self.left != null) {
if (parent == null) {
root = self.left;
} else {
if (parent.left == self) {
parent.left = self.left;
}
if (parent.right == self) {
parent.right = self.left;
}
}
}
//如果左右子树都有,没涉及父节点,因此不用考虑
if (self.right != null && self.left != null) {
Node temp = self.right;
while (temp.left != null) {
temp = temp.left;
}
remove(temp.id);
self.id = temp.id;
}
}
}
}