什么是二叉排序树?
二叉排序树就是给一个根节点,在根节点右边的节点的值比它大,在根节点左边的值比他小。
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
代码实现:
public static void main(String[] args) {
int[] arr={7,3,10,12,5,1,9,2};
BinarySortTree binarySortTree=new BinarySortTree();
//循环地添加节点到二叉排序树
for (int i = 0; i <arr.length ; i++) {
binarySortTree.add(new Node(arr[i]));
}
//中序遍历二叉树
System.out.println("中序遍历");
binarySortTree.infixOrder();
binarySortTree.delNode(7);
System.out.println("删除7节点后");
binarySortTree.infixOrder();
}
}
class Node {
int value;
Node left;
Node right;
public Node(int value) {
this.value=value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
//中序遍历,把数组变成二叉树
public void infixOder() {
if (this.left != null) {
this.left.infixOder();
}
System.out.println(this);
if (this.right != null) {
this.right.infixOder();
}
}
//添加节点的方法
//递归的形式添加节点,注意需要满足二叉排序树的要求
//注意:新添加的节点都会陈导最下面去,成为一个叶子节点!!!!!!!!!!
public void add(Node node) {
//如果传入的值为空,则直接返回
if (node == null) {
return;
}
//判断传入的节点的值,和当前子树跟节点值的关系
if (node.value < this.value) {
//如果当前节点左子节点为null
if (this.left == null) {
this.left = node;
} else {
this.left.add(node);
}
} else {//要添加的节点的值大于等于当前节点的值
if (this.right == null) {
this.right = node;
} else {
this.right.add(node);
}
}
}
//查找要删除的节点
/**
* @param value 希望删除的节点的值
* @return 如果找到返回该节点, 否则返回null
*/
public Node serach(int value) {
if (value == this.value) { //找到的就是该节点
return this;
} else if (value < this.value) { //向左子树进行查找
if (this.left == null) { //如果左子节点为空(一开始的时候和递归到最后还小),返回null
return null;
}
return this.left.serach(value); //一直递归,直到找到或者它的值小于最小的值
} else { //如果查找到的值大于当前节点,向有递归查找
if (this.right == null) {
return null;
}
return this.right.serach(value);
}
}
//查找要删除的父节点
//删除操作时需要找到该节点的父节点
/**
* @param value 要找到的删除的节点
* @return 返回的是要删除的节点的父节点, 如果没有返回null
*/
public Node searchParent(int value) {
//如果当前节点就是要删除的节点的父节点,就返回
if ((this.left != null) && (this.left.value == value) || (this.right != null) && (this.right.value == value)) {
return this;
} else {
//如果查找的值小于当前节点的值,并且当前节点的左子节点不为空
if (value < this.value && this.left != null) {
return this.left.searchParent(value);//向左子树递归查找
} else if (value >= this.value && this.right != null) {
return this.right.searchParent(value);//向右子树递归查找
} else {
return null;//没有找到父节点
}
}
}
}
class BinarySortTree{
private Node root;
//添加节点的方法
public void add(Node node){
if (root==null){
root=node;//如果root为空则直接让root指向node
}else {
root.add(node);
}
}
//中序遍历
public void infixOrder(){
if (root!=null){
root.infixOder();
}else {
System.out.println("二叉排序树为空,不能遍历");
}
}
//查找要删除的节点
public Node search(int value){
if (root!=null){
return root.serach(value);
}else {
return null;
}
}
//查找父节点
public Node searchParent(int value){
if (root==null){
return null;
}else {
return root.searchParent(value);
}
}
/** 1,编写方法,返回以node为根节点的二叉排序树的最小节点的值
* 2,删除node为跟节点的二叉排序树的最小节点
*
* @param node 要删除的节点(当做二叉树的根节点)
* @return 返回的以node为跟节点的二叉排序树的最小节点的值
*/
public int delRightTreeMin(Node node){
Node target=node;
//循环地查找左子节点,就会找到最小值
while (target.left!=null){
target=target.left;
}
//这时target就指向了最小节点
//删除最小节点(该节点肯定是最叶子节点)
delNode(target.value);
return target.value;
}
//删除节点
public void delNode(int value){
if (root==null){
return;
}else {
//1,需要先去找到要删除的节点targetNode
Node targetNode=search(value);
//如果没有找到要删除的几点
if (targetNode==null){
return;
}
//如果我们发现当前这棵二叉排序树只有一个节点,则删除这个节点
if (root.left==null && root.right==null){
root=null;
return;
}
//去找到targetNode的父节点
Node parent=searchParent(value);
//一,如果要删除的节点是叶子节点
if (targetNode.left==null && targetNode.right==null){
//判断targetNode是父节点的左子节点,还是右子节点
if (parent.left!=null && parent.left.value==value){
//是左子节点
parent.left=null;
}else if (parent.right!=null && parent.right.value==value){
//是右子节点
parent.right=null;
}
}
//二,删除有左右两个子树的节点
else if (targetNode.left!=null && targetNode.right!=null){
//在我们找到右节点左子树最小值minVal的时候我们也把他删除了
//但是我们把这个值存放起来了并且赋值给了当前要删除的值targetNode.value
int minVal=delRightTreeMin(targetNode.right);
targetNode.value=minVal;
}
//三,删除只有一颗子树的节点
else {
//如果要删除的节点有左子树
if (targetNode.left!=null){
if (parent!=null){
//如果targetNode是parent的左子节点
if (parent.left.value==value){
parent.left=targetNode.left;
}else { //targetNode是parent的右子节点
parent.right=targetNode.left;
}
}else { //如果要删除的节点有右子节点
if (parent!=null){
//如果targetNode是parent的左子节点
if (parent.left.value==value){
parent.left=targetNode.right;
}else {
//如果targetNode是parent的右子节点
parent.right=targetNode.right;
}
}else {
root=targetNode.right;
}
}
}
}
}
}
详细分析: