创建一颗排序二叉树没什么好讲的,直接递归,然后添加到叶子节点上。我这里主要讲解如何删除节点!(Node里面的search和searchFather方法用来准备删除工作的)
class Node{
Node leftNode;
Node rightNode;
int val;
public Node(int val) {
this.val = val;
}
@Override
public String toString() {
return "Node{" +
"val=" + val +
'}';
}
public void add(Node node) { //生成一颗顺序二叉树
if (node.val > this.val) {
if (this.rightNode == null) {
this.rightNode = node;
}
else {
this.rightNode.add(node);
}
}
else {
if (this.leftNode == null) {
this.leftNode = node;
}
else {
this.leftNode.add(node);
}
}
}
public void infixOrder() { //中序遍历
if (this.leftNode != null) {
this.leftNode.infixOrder();
}
System.out.println(this);
if (this.rightNode != null) {
this.rightNode.infixOrder();
}
}
public Node search(int val) { //查找当前节点
Node node = null;
if (val == this.val) {
return this;
}
else if (val > this.val) {
node = this.rightNode.search(val);
}
else {
node = this.leftNode.search(val);
}
return node;
}
//查找你需要查找的节点的父节点
public Node searchFather(int val) {
if ((this.leftNode != null && this.leftNode.val == val) || (this.rightNode != null && this.rightNode.val == val)) {
return this;
}
else {
if (val < this.val && this.leftNode != null) {
return this.leftNode.searchFather(val);
}
else if (val > this.val && this.rightNode != null) {
return this.rightNode.searchFather(val);
}
else {
return null;
}
}
}
}
我们先分析树的结构:删除树的节点其实就三种。
1,没有子节点的节点
2.有一个子节点的节点
3.有两个子节点的节点
那么第一种删除方法就很简单了,直接想办法把它置为空,第二种就是把子节点覆盖它,第三种简单的说就是找到要删除的节点后,再找到它的右子树的最小节点,或者左子树最大的节点然后覆盖这个值就解决了。
class BinarySortTreeDemo {
private Node root;
public void add(Node node) {
if (this.root == null) {
this.root = node;
}
else {
this.root.add(node);
}
}
public Node searchFather(int val) {
if (root == null) {
System.out.println("树为空");
return null;
}
else {
return this.root.searchFather(val);
}
}
public Node search(int val) {
return root.search(val);
}
public void infixOrder() {
if (root != null) {
root.infixOrder();
}
else {
System.out.println("二叉树是空");
}
}
/**
* 任务一: node 节点当做一颗二叉排序树的根节点,返回该二叉树最小节点的值
*
* 任务二: 删除以node为根节点的二叉排序树的最小节点
* @param node
* @return
*/
public int del(Node node) {
Node target = node;
while (target.leftNode != null) {
target = target.leftNode;
}
delNode(target.val); //这里因为找右子树最小节点肯定是叶子节点,也就是没有子节点的节点,所以可以调用这个方法。
return target.val;
}
public void delNode(int val) {
if (this.root == null) {
return;
}
else {
Node target = search(val);
Node targetFather = searchFather(val);
if (target == null) {
return;
}
//删除没有子节点的节点
if (target.leftNode == null && target.rightNode == null) {
if (targetFather.leftNode != null && targetFather.leftNode == target) {
targetFather.leftNode = null;
}
else {
targetFather.rightNode = null;
}
}//删除有两个子节点的节点,最后看这个
else if (target.leftNode != null && target.rightNode != null) {
target.val = del(target.rightNode);
}
else { //只有一个子节点的节点
if (targetFather.leftNode.val == target.val) {
if (target.leftNode != null) {
targetFather.leftNode = target.leftNode;
}
else {
targetFather.leftNode = target.leftNode;
}
}
else {
if (target.rightNode != null) {
targetFather.rightNode = target.rightNode;
}
else {
targetFather.rightNode = target.leftNode;
}
}
}
}
}
}