二分搜索树删除任意节点
只有右孩子的节点
与删除最小元素的情况相同
只有左孩子的节点
与删除最大元素的情况相同
叶子节点
即可以当做只有左孩子的节点也可以当做只有右孩子的节点
既有左孩子又有右孩子的节点
待删除的节点记作d
找到右子树中最小的节点来替代待删除的节点,右子树中最小的节点记作s,s是d的后继
s=min(d->right)
s->right=delMin(d->right)
s-left=d->left
二分搜索树的相关实现 ##
二分搜索树的相关实现
package com.learn.xt.bst;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class BST <E extends Comparable<E>> {
private class Node{
public E e;
public Node left;
public Node right;
public Node(E e){
this.e=e;
this.left=null;
this.right=null;
}
}
private Node root;
private int size;
public BST(){
root=null;
size=0;
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public void add(E e){
root=add(root,e);
}
/**
* 向以node为根的二分搜索树中插入元素e
* @param node
* @param e
* @return 返回根节点
*/
private Node add(Node node,E e){
if(node==null){
size++;
return new Node(e);
}
if(e.compareTo(node.e)<0){
node.left=add(node.left,e);
}else if(e.compareTo(node.e)>0){
node.right=add(node.right,e);
}
return node;
}
/**
* 查看二分搜索树中是否包含元素e
* @param e
* @return
*/
public boolean contain(E e){
return contain(root,e);
}
/**
* 查看以node为根的二分搜索树中是否包含元素e
* @param node
* @param e
* @return
*/
public boolean contain(Node node,E e){
if(node==null){
return false;
}
if(e.compareTo(node.e)<0){
return contain(node.left,e);
}else if(e.compareTo(node.e)>0){
return contain(node.right,e);
}else{
return true;
}
}
/**
* 中序遍历
* 二分搜索树的中序输出是排好序的
*/
public void inOrder(){
inOrder(root);
}
/**
* 以node为根二分搜索树的中序遍历
* @param node
*/
private void inOrder(Node node){
if(node==null){
return;
}
inOrder(node.left);
System.out.println(node.e);
inOrder(node.right);
}
/**
* 后续遍历
*/
public void bgOrder(){
bgOrder(root);
}
/**
* 以node为根二分搜索树的后续遍历
* @param node
*/
private void bgOrder(Node node){
if(node==null){
return;
}
bgOrder(node.left);
bgOrder(node.right);
System.out.println(node.e);
}
/**
* 前序遍历
*/
public void preOrder(){
preOrder(root);
}
/**
* 以node为根二分搜索树的前序遍历
* @param node
*/
private void preOrder(Node node){
if(node==null){
return;
}
System.out.println(node.e);
preOrder(node.left);
preOrder(node.right);
}
public static void main(String[] args) {
BST<Integer> bst=new BST<>();
int[] nums={1,5,3,6,4};
for(int num:nums){
bst.add(num);
}
bst.preOrder();
}
@Override
public String toString(){
StringBuilder res=new StringBuilder();
generateBSTString(root,0,res);
return res.toString();
}
private void generateBSTString(Node node,int depth,StringBuilder res){
if(node==null){
res.append(generateDepthString(depth)+"null\n");
return;
}
res.append(generateDepthString(depth).concat(node.e+"\n"));
generateBSTString(node.left,depth+1,res);
generateBSTString(node.right,depth+1,res);
}
/**
* 用来生成前面的--
* @param depth 树的深度
* @return
*/
private String generateDepthString(int depth){
StringBuilder res=new StringBuilder();
for(int i=0;i<depth;i++){
res.append("--");
}
return res.toString();
}
/**
* 二分搜索树的前序非递归写法
* 需要借助栈的数据结构,
* 1.先初始化栈,把跟节点入栈
* 2.再循环,直到栈为空
* 2.1 出栈,获取当前栈
* 2.2 访问当前栈
* 2.3 当前栈的右子树不为空时将当前栈的右子树入栈
* 2.4 当前栈的左子树不为空时将当前栈的左子树入栈
*/
public void preOrderNR(){
Stack<Node> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
Node curNode=stack.pop();
System.out.println(curNode.e);
if(curNode.right!=null){
stack.push(curNode.right);
}
if(curNode.left!=null){
stack.push(curNode.left);
}
}
}
/**
* 广度优先遍历
*/
public void levelOrder(){
Queue<Node> que=new LinkedList<>();
que.add(root);
while(!que.isEmpty()){
Node curentNode = que.remove();
System.out.println(curentNode.e);
if(curentNode.left!=null){
que.add(curentNode.left);
}
if(curentNode.right!=null){
que.add(curentNode.right);
}
}
}
/**
* 返回二分搜索树的最小元素
* @return
*/
public E minmum(){
if(size==0){
throw new IllegalArgumentException("BST is empty");
}
return minmum(root).e;
}
/**
* 寻找二分搜索树中以node为根的最小的节点
* @param node
* @return
*/
public Node minmum(Node node){
if(node.left==null){
return node;
}
return minmum(node.left);
}
/**
* 返回二分搜索树的最大元素
* @return
*/
public E maxmum(){
if(size==0){
throw new IllegalArgumentException("BST is empty");
}
return maxmum(root).e;
}
/**
* 寻找二分搜索树中以node为根的最小的节点
* @param node
* @return
*/
public Node maxmum(Node node){
if(node.right==null){
return node;
}
return maxmum(node.right);
}
/**
* 删除最小的元素
* @return
*/
public E removeMin(){
E ret=minmum();
root=removeMin(root);
return ret;
}
/**
* 删除以node为根的最小元素
* @param node
* @return
*/
public Node removeMin(Node node){
if(node.left==null){
Node rigthNode=node.right;
node.right=null;
size--;
return rigthNode;
}
node.left=removeMin(node.left);
return node;
}
/**
* 删除二分搜索树中的任意元素
*/
public void remove(E e){
root=remove(root,e);
}
/**
* 删除以node为根,节点元素为e的节点
* @param node
* @param e
* @return 返回新的二分搜索树
*/
private Node remove(Node node,E e){
if(node==null)
return null;
if(e.compareTo(node.e)<0){
node.left=remove(node.left,e);
return node;
}else if(e.compareTo(node.e)>0){
node.right=remove(node.right,e);
return node;
}else{//e==node.e的情况 也是递归结束的情况
//如果左子树为null
if(node.left==null){
Node rightNode=node.right;
node.right=null;
size--;
return rightNode;
}
//如果右子树为null
if(node.right==null){
Node leftNode=node.left;
node.left=null;
size--;
return leftNode;
}
//待删除节点左右子树均不为null
Node successor=minmum(node.right);
successor.right=removeMin(node.right);
successor.left=node.left;
node.left=null;
node.right=null;
return successor;
}
}
}