二叉排序树的查找
首先二叉排序树,是将一个无序队列或者数组,循环创建后中序遍历形成有序。
依次和根节点比较,如果相等则返回,如果不相等,则判断左子树和右子树上的值
如果比左子树的值小,则进行左递归查找,如果比右子树的值大,则进行右递归查找。
二叉排序树的删除
分多种情况,如果删除的是叶子节点 则,先找到 parentNode,判断要删除的是左孩子还是右孩子
进行删除
//是叶子节点,再判断是父节点的 左子节点 还是右子节点
if(node.getLeft()==null&&node.getRight()==null){
if(parentNode.getLeft()!=null && parentNode.getLeft().getValue()==value){
parentNode.setLeft(null);
}else if(parentNode.getRight()!=null && parentNode.getRight().getValue()==value){
parentNode.setRight(null);
}
如果要删除的节点不是叶子节点(有一个左孩子或者右孩子),同样先找到parentNode,判断要删除的是左孩子还是右孩子。 分四种情况
//有一颗子树
else{
//如果要删除节点的左子树不为空
if(node.getLeft()!=null){
//如果父节点的左子树是 要删除节点
if(parentNode.getLeft()!=null&&parentNode.getLeft().getValue()==value){
parentNode.setLeft(node.getLeft());
}//如果父节点的右子树是 要删除节点
else if(parentNode.getRight()!=null&&parentNode.getRight().getValue()==value){
parentNode.setRight(node.getLeft());
}
}//如果要删除节点的右子树不为空
else{
//如果父节点的左子树是 要删除节点
if(parentNode.getLeft()!=null&&parentNode.getLeft().getValue()==value){
parentNode.setLeft(node.getRight());
}//如果父节点右子树是 要删除节点
else if(parentNode.getRight()!=null&&parentNode.getRight().getValue()==value){
parentNode.setRight(node.getRight());
}
}
}
如果要删除的节点都有左右孩子,则先找到 要删除的节点的左子树的最大值,或者右子树的最小值,进行删除,并修改 要删除节点的值
}
}//不是叶子节点有两颗子树
else if(node.getLeft()!=null&&node.getRight()!=null){
//判断是父节点的 左孩子还是右孩子
if(parentNode.getLeft().getValue()==node.value){
//找右子树的最小节点 删除 并赋给当前要删除的节点 // 也可以找左子树的最大节点
Node2 tar = deleteAndReturn(node.getRight());
node.setValue(tar.getValue());
}else{
Node2 tar = deleteAndReturn(node.getRight());
node.setValue(tar.getValue());
}
}
代码如下所示:
package com.wuzhixin.tree;
import java.util.ArrayList;
import java.util.List;
public class BinarySortTree {
public static void main(String[] args) {
int []arr = {7,3,10,12,5,1,9};
List<Node2> nodes = new ArrayList<>();
Node2 node = null;
SortTree sortTree = new SortTree();
for(int i=0;i<arr.length;i++){
node = new Node2(arr[i]);
sortTree.add(node);
}
sortTree.getRoot().midShow();
sortTree.getRoot().preShow();
Node2 node2 = sortTree.getRoot().searchNode(10);
Node2 parentNode2 = sortTree.getRoot().searchParentNode(10);
System.out.println("**********************");
System.out.println(node2);
System.out.println(parentNode2);
sortTree.midOrder();
System.out.println("************************");
sortTree.deleteNode(1);
sortTree.deleteNode(5);
sortTree.deleteNode(3);
sortTree.midOrder();
}
}
class SortTree{
private Node2 root;
public Node2 getRoot() {
return root;
}
public void setRoot(Node2 root) {
this.root = root;
}
public void add (Node2 node){
if(root==null){
root=node;
}
else{
root.add(node);
}
}
//前序遍历
public void preOrder(){
if(root==null){
return;
}
root.preShow();
}
//中序遍历
public void midOrder(){
if(root==null){
return;
}else{
root.midShow();
}
}
//查找要删除的节点
public Node2 findNode(int value){
if(root==null){
return null;
}
return root.searchNode(value);
}
//查找要删除节点的父节点
public Node2 findParentNode(int value){
if(root==null){
return null;
}
return root.searchParentNode(value);
}
//删除叶子节点
public void deleteNode(int value){
if(root==null){
return;
}else {
root.deleteNode(value);
}
}
}
class Node2 {
private Node2 left;
private Node2 right;
private Integer value ;
public Node2(Integer value) {
this.value = value;
}
@Override
public String toString() {
return value +" "
;
}
public Node2 getLeft() {
return left;
}
public void setLeft(Node2 left) {
this.left = left;
}
public Node2 getRight() {
return right;
}
public void setRight(Node2 right) {
this.right = right;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
/**
* 添加节点的方法,
* 递归的形式添加节点,满足二叉排序树
* @param node
*/
public void add(Node2 node){
if(node == null){
return;
}
//如果当前加入的节点小于当树的根节点,则向左边添加
if(node.getValue()<=this.getValue()){
if(this.getLeft()==null){
this.setLeft(node);
}//否则向左递归添加
else{
this.getLeft().add(node);
}
}else{
if(this.getRight()==null){
this.setRight(node);
}else{
this.getRight().add(node);
}
}
}
//前序遍历
public void preShow(){
System.out.println(this);
if(this.getLeft()!=null){
this.getLeft().preShow();
}
if(this.getRight()!=null){
this.getRight().preShow();
}
}
// 中序遍历
public void midShow(){
if(this.getLeft()!=null){
this.getLeft().midShow();
}
System.out.print(this+" ");
if(this.getRight()!=null){
this.getRight().midShow();
}
}
public Node2 searchNode(int value){
//如果当前节点的值 等于
if(this.value==value){
return this;
}else {
if (this.value > value && this.getLeft() != null) {
return this.getLeft().searchNode(value);
} else if(this.value<value && this.getRight()!=null) {
return this.getRight().searchNode(value);
} else{
return null;
}
}
}
//查找要删除的父节点
public Node2 searchParentNode(int value){
if(this.getLeft()!=null&&this.getLeft().getValue()==value|| this.getRight()!=null&&this.getRight().getValue()==value){
return this;
}else if(this.getLeft()!=null&&this.getValue()>value){
return this.getLeft().searchParentNode(value);
}else if(this.getRight()!=null&&this.getValue()<value){
return this.getRight().searchParentNode(value);
}else{
return null;
}
}
public void deleteNode(int value){
Node2 node = this.searchNode(value);
if(node==null){
System.out.println("没有该节点,无法删除");
return;
}
Node2 parentNode = this.searchParentNode(value);
//是叶子节点,再判断是父节点的 左子节点 还是右子节点
if(node.getLeft()==null&&node.getRight()==null){
if(parentNode.getLeft()!=null && parentNode.getLeft().getValue()==value){
parentNode.setLeft(null);
}else if(parentNode.getRight()!=null && parentNode.getRight().getValue()==value){
parentNode.setRight(null);
}
}//不是叶子节点有两颗子树
else if(node.getLeft()!=null&&node.getRight()!=null){
//判断是父节点的 左孩子还是右孩子
if(parentNode.getLeft().getValue()==node.value){
//找右子树的最小节点 删除 并赋给当前要删除的节点 // 也可以找左子树的最大节点
Node2 tar = deleteAndReturn(node.getRight());
node.setValue(tar.getValue());
}else{
Node2 tar = deleteAndReturn(node.getRight());
node.setValue(tar.getValue());
}
}//有一颗子树
else{
//如果要删除节点的左子树不为空
if(node.getLeft()!=null){
//如果父节点的左子树是 要删除节点
if(parentNode.getLeft()!=null&&parentNode.getLeft().getValue()==value){
parentNode.setLeft(node.getLeft());
}//如果父节点的右子树是 要删除节点
else if(parentNode.getRight()!=null&&parentNode.getRight().getValue()==value){
parentNode.setRight(node.getLeft());
}
}//如果要删除节点的右子树不为空
else{
//如果父节点的左子树是 要删除节点
if(parentNode.getLeft()!=null&&parentNode.getLeft().getValue()==value){
parentNode.setLeft(node.getRight());
}//如果父节点右子树是 要删除节点
else if(parentNode.getRight()!=null&&parentNode.getRight().getValue()==value){
parentNode.setRight(node.getRight());
}
}
}
}
//传入根节点,找到该树的最小节点,并删除 返回
public Node2 deleteAndReturn(Node2 node){
Node2 target = node;
while(target.getLeft()!=null){
target=target.getLeft();
}
deleteNode(target.getValue());
return target;
}
}