1、删除二分搜索树的最大元素
(1)寻找二分搜索树的最大元素
//先找到最大节点
T maxNodeVal =findmaxnodeDG();
if (maxNodeVal==null){
System.out.println("isEmpty");
return ;
}
(2)返回以node为根的二分搜索树的最大值所在的节点
if (node.right==null){
//进行删除操作
Node leftNode =node.left;
node.left =null;
return leftNode;
}
node.right =removeMaxNode(node.right);
return node;
2、删除二分搜索树的最小元素
同理,
//删除最小元素
private void removeMixNode(){
//先找到最小节点
T minNodeVal =findminnodeDG();
if (minNodeVal==null){
System.out.println("isEmpty");
return ;
}
System.out.println(minNodeVal.toString());
//进行删除操作
root= removeMixNode(root);
}
private Node removeMixNode(Node node) {
if (node.left==null){
//进行删除操作
Node rightNode =node.right;
node.right =null;
return rightNode;
}
node.left =removeMixNode(node.left);
return node;
}
1、删除二分搜索树的任意元素
(1)左右节点都为空
delNode=null;
(2)左节点不为空,右节点为空
leftNode =delNode.left;
delNode.left = null;
return leftNode;
(3)右节点不为空,左节点为空
rightNode =delNode.right;
delNode.right = null;
return rightNode;
(4)左右节点都不为空
//左右节点都不为空
//1、找node 的后继(node.right中的最小节点)
Node t = findminnodeDG(node.right);
//2、node.right 中删除最小节点
Node node1 = removeMixNode(node.right);
//3、使用后继节点替换node
t.left =node.left;
t.right =node1;
//4、生成新树,新树的根节点就是后继节点,返回新树根节点
node.left=node.right=null; //断开删除节点的左右节点
return t;
/删除任意节点
public T removeNode(T val){
//判断根是否为0
if (root==null){
System.out.println("根为0");
return null;
}
//不为零,则需要查找节点
Node node=findNodeDG(root,val);
if (node!=null){
//删除节点
root= removeNode(root,val);
return node.val;
}
return null;
}
/**
* 从以root为根的二分搜索树中删除值为val的节点
* @param node
* @param val
* @return
*/
private Node removeNode(Node node,T val){
//递归到底的情况,找到了删除的节点
//左节点为空,右节点为空,左右节点都为空
if (node.val.compareTo(val)==0){
if (node.left==null){
Node rightNode =node.right;
node.right =null;
return rightNode;
}else if (node.right==null){
Node leftNode =node.left;
node.left =null;
return leftNode;
}else {
//左右节点都不为空
//1、找node 的后继(node.right中的最小节点)
Node t = findminnodeDG(node.right);
//2、node.right 中删除最小节点
Node node1 = removeMixNode(node.right);
//3、使用后继节点替换node
t.left =node.left;
t.right =node1;
//4、生成新树,新树的根节点就是后继节点,返回新树根节点
node.left=node1=null;
return t;
}
}
//递归操作
if (node.val.compareTo(val)>0){
node.left=removeNode(node.left,val);
}else {
node.right=removeNode(node.right,val);
}
return node;
}
//查找节点
private Node findNodeDG(Node node, T val) {
//最终没有找到节点,返回null
if (node ==null){
return null;
}
if (node.val.compareTo(val)==0){
return node;
}else if (node.val.compareTo(val)>0){
return findNodeDG(node.left,val);
}else {
return findNodeDG(node.right,val);
}
}
完整代码
package binary;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class BinarySearch<T extends Comparable<T>> {
public static void main(String[] args) {
int[] arr = {28, 23, 15, 56, 34, 78};
BinarySearch<Integer> bs = new BinarySearch<>();
for (int i = 0; i < arr.length; i++) {
bs.add(arr[i]);
}
System.out.println("是否包含15:" + (bs.contains(15) != null));
System.out.println("是否包含100:" + (bs.contains(100) != null));
System.out.println("--------中序遍历----------");
List<Integer> l = bs.middleorder();
l.stream().forEach(System.out::println);
System.out.println("--------前序遍历----------");
List<Integer> l1 = bs.preorder();
l1.stream().forEach(System.out::println);
System.out.println("--------后序遍历----------");
List<Integer> l2 = bs.lastorder();
l2.stream().forEach(System.out::println);
System.out.println("--------层序遍历----------");
List<Integer> l3 =bs.levelorder();
l3.stream().forEach(System.out::println);
System.out.println("-------查找最小元素--------");
System.out.println(bs.findminnode());
System.out.println("-------查找最大元素---------");
System.out.println(bs.finfmaxnode());
System.out.println("-------查找最小元素- 递归-------");
System.out.println(bs.findminnodeDG());
System.out.println("-------查找最大元素- 递归-------");
System.out.println(bs.findmaxnodeDG());
/* System.out.println("\n----------删除最小节点--------------");
Integer val = bs.findminnodeDG();
System.out.println(val != null ? val : "null");
//删除最小元素
bs.removeMixNode();
//层序遍历
l3.stream().forEach(item -> System.out.print(item + " "));*/
/* System.out.println("\n----------删除最大节点--------------");
Integer val = bs.findmaxnodeDG();
System.out.println(val != null ? val : "null");
//删除最大元素
bs.removeMaxNode();
//层序遍历
l3.stream().forEach(item -> System.out.print(item + " "));*/
System.out.println("---------------删除任意节点--------------");
Integer integer = bs.removeNode(23);
System.out.println(String.valueOf(integer));
l3= bs.levelorder();
l3.stream().forEach(item -> System.out.print(item + " "));
}
class Node {
T val;
Node left;
Node right;
public Node(T val) {
this.val = val;
}
}
//定义根节点
Node root;
//构造方法
public BinarySearch() {
this.root = null;
}
//判断这棵树是否为空
public boolean isEmpty() {
return this.root == null;
}
//1、添加节点
public void add(T ele) {
//利用递归添加节点
root = add(root, ele);
}
private Node add(Node root, T ele) {
//如果根节点为空,创建一个新得二叉树,传ele参数进去
if (root == null) {
Node node = new Node(ele);
return node;
}
//根节点不为空,将要添加的元素与跟的值进行比较大小
//递归操作 不考虑等于的情况
if (ele.compareTo(root.val) > 0) {
root.right = add(root.right, ele);
} else {
root.left = add(root.left, ele);
}
return root;
}
//2、查询二叉树节点是否包含节点
public Node contains(T ele) {
return contains(root, ele);
}
private Node contains(Node root, T ele) {
if (root == null) {
return null;
}
//递归
T val = root.val;
if (ele.compareTo(val) == 0) {
return root;
} else if (ele.compareTo(val) > 0) {
return contains(root.right, ele);
} else {
return contains(root.left, ele);
}
}
//3、中序遍历 (按顺序)
public List<T> middleorder() {
List<T> list = new LinkedList<>();
middleorder(root, list);
return list;
}
private void middleorder(Node root, List<T> list) {
//遍历到最后
if (root == null) {
return;
}
//左中右 遍历左边 返回根节点 遍历右边
middleorder(root.left, list);
list.add(root.val);
middleorder(root.right, list);
return;
}
//3、后序遍历
public List<T> lastorder() {
List<T> list = new LinkedList<>();
lastorder(root, list);
return list;
}
private void lastorder(Node root, List<T> list) {
//遍历到最后
if (root == null) {
return;
}
//左右中 遍历左边 返回根节点 遍历右边
middleorder(root.left, list);
middleorder(root.right, list);
list.add(root.val);
return;
}
//3、前序遍历
public List<T> preorder() {
List<T> list = new LinkedList<>();
preorder(root, list);
return list;
}
private void preorder(Node root, List<T> list) {
//遍历到最后
if (root == null) {
return;
}
//中左右 遍历左边 返回根节点 遍历右边
list.add(root.val);
middleorder(root.left, list);
middleorder(root.right, list);
return;
}
//4、层序遍历(广度优先)
public List<T> levelorder() {
List<T> lis = new LinkedList<>();
if (root != null) {
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
Node node = queue.poll();
lis.add(node.val);
if (node.left != null) {
queue.offer(node.left);//队列加入的方法
}
if (node.right != null) {
queue.offer(node.right);
}
}
}
return lis;
}
//5、查找最大最小元素
public T findminnode(){
if (root==null){
return null;
}
Node curnode=root; //临时变量指向根节点
while (curnode.left!=null){
curnode=curnode.left;
}
return curnode.val;
}
public T finfmaxnode(){
if (root==null){
return null;
}
Node curnode=root;
while (curnode.right!=null){
curnode=curnode.right;
}
return curnode.val;
}
//5、查找最小元素 递归
public T findminnodeDG(){
if (root==null){
return null;
}
return findminnodeDG(root).val;//从root节点开始查找最小元素
}
private Node findminnodeDG(Node root) {
if (root.left==null){
return root;
}
return findminnodeDG(root.left);//向左遍历
}
//查找最大元素 递归
public T findmaxnodeDG(){
if (root==null){
return null;
}
return findmaxnodeDG(root);
}
private T findmaxnodeDG(Node root) {
if (root.right==null){
return root.val;
}
return findmaxnodeDG(root.right);
}
//删除最小元素
private void removeMixNode(){
//先找到最小节点
T minNodeVal =findminnodeDG();
if (minNodeVal==null){
System.out.println("isEmpty");
return ;
}
System.out.println(minNodeVal.toString());
//进行删除操作
root= removeMixNode(root);
}
private Node removeMixNode(Node node) {
if (node.left==null){
//进行删除操作
Node rightNode =node.right;
node.right =null;
return rightNode;
}
node.left =removeMixNode(node.left);
return node;
}
//删除最大节点
private void removeMaxNode(){
//先找到最大节点
T maxNodeVal =findmaxnodeDG();
if (maxNodeVal==null){
System.out.println("isEmpty");
return ;
}
System.out.println(maxNodeVal.toString());
//进行删除操作
root= removeMaxNode(root);
}
private Node removeMaxNode(Node node) {
if (node.right==null){
//进行删除操作
Node leftNode =node.left;
node.left =null;
return leftNode;
}
node.right =removeMaxNode(node.right);
return node;
}
//删除任意节点
public T removeNode(T val){
//判断根是否为0
if (root==null){
System.out.println("根为0");
return null;
}
//不为零,则需要查找节点
Node node=findNodeDG(root,val);
if (node!=null){
//删除节点
root= removeNode(root,val);
return node.val;
}
return null;
}
/**
* 从以root为根的二分搜索树中删除值为val的节点
* @param node
* @param val
* @return
*/
private Node removeNode(Node node,T val){
//递归到底的情况,找到了删除的节点
//左节点为空,右节点为空,左右节点都为空
if (node.val.compareTo(val)==0){
if (node.left==null){
Node rightNode =node.right;
node.right =null;
return rightNode;
}else if (node.right==null){
Node leftNode =node.left;
node.left =null;
return leftNode;
}else {
//左右节点都不为空
//1、找node 的后继(node.right中的最小节点)
Node t = findminnodeDG(node.right);
//2、node.right 中删除最小节点
Node node1 = removeMixNode(node.right);
//3、使用后继节点替换node
t.left =node.left;
t.right =node1;
//4、生成新树,新树的根节点就是后继节点,返回新树根节点
node.left=node1=null;
return t;
}
}
//递归操作
if (node.val.compareTo(val)>0){
node.left=removeNode(node.left,val);
}else {
node.right=removeNode(node.right,val);
}
return node;
}
//查找节点
private Node findNodeDG(Node node, T val) {
//最终没有找到节点,返回null
if (node ==null){
return null;
}
if (node.val.compareTo(val)==0){
return node;
}else if (node.val.compareTo(val)>0){
return findNodeDG(node.left,val);
}else {
return findNodeDG(node.right,val);
}
}
}