实现一个二叉搜索树,提供添加元素、删除元素、前序、中序、后序遍历、节点个数、查询单一节点等功能,为了实 现BinarySearchTree,需要定义好一个节点类型,如下 : 定义树接口如下: Node<T> findTargetNode(T element); 注:接口中带 TODO 字样的方法,是视频中没有写的,需要你们自己实现。 写一个BinarySearchTree 来实现 Tree 接口,定义如下: public class BinarySearchTree<T extends Comparable<T>> implements Tree<T> { //属性: //1. 指向根节点 private Node<T> root; //2.树中节点的数量 private int size; //TODO 实现接口所有的方法,另外,要实现remove方法,在此类中还要额外提供 findParentNode(T target) 方法和 findMinNodeFromRight(Node<T> target) 方法
时间: 2024-03-26 15:35:44 浏览: 55
binary search tree 二叉搜索树的C++实现,有插入、删除、查找、查找最大最小等功能
5星 · 资源好评率100%
好的,我可以帮你解答这个问题。下面是代码实现:
节点类 Node:
```java
public class Node<T extends Comparable<T>> {
T data; // 节点数据
Node<T> left; // 左孩子
Node<T> right; // 右孩子
public Node(T data) {
this.data = data;
}
}
```
二叉搜索树 BinarySearchTree:
```java
public class BinarySearchTree<T extends Comparable<T>> implements Tree<T> {
private Node<T> root; // 根节点
private int size; // 节点数量
/**
* 添加节点
*/
@Override
public void add(T element) {
if (element == null) {
return;
}
root = add(root, element);
size++;
}
/**
* 在以 node 为根节点的子树中添加元素,并返回添加后的根节点
*/
private Node<T> add(Node<T> node, T element) {
if (node == null) {
return new Node<>(element);
}
if (element.compareTo(node.data) < 0) {
node.left = add(node.left, element);
} else if (element.compareTo(node.data) > 0) {
node.right = add(node.right, element);
}
return node;
}
/**
* 删除节点
*/
@Override
public void remove(T element) {
if (element == null) {
return;
}
root = remove(root, element);
}
/**
* 在以 node 为根节点的子树中删除元素,并返回删除后的根节点
*/
private Node<T> remove(Node<T> node, T element) {
if (node == null) {
return null;
}
if (element.compareTo(node.data) < 0) {
node.left = remove(node.left, element);
return node;
} else if (element.compareTo(node.data) > 0) {
node.right = remove(node.right, element);
return node;
} else {
if (node.left == null) {
Node<T> rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
if (node.right == null) {
Node<T> leftNode = node.left;
node.left = null;
size--;
return leftNode;
}
// 左右子树均不为空的情况
Node<T> successor = findMinNodeFromRight(node.right); // 找到右子树中的最小节点
successor.right = removeMinNodeFromRight(node.right); // 删除右子树中的最小节点
successor.left = node.left;
node.left = node.right = null;
return successor;
}
}
/**
* 从以 node 为根节点的子树中删除最小节点,并返回删除后的根节点
*/
private Node<T> removeMinNodeFromRight(Node<T> node) {
if (node.left == null) {
Node<T> rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
node.left = removeMinNodeFromRight(node.left);
return node;
}
/**
* 查找节点
*/
@Override
public Node<T> findTargetNode(T element) {
if (element == null) {
return null;
}
return findTargetNode(root, element);
}
/**
* 在以 node 为根节点的子树中查找元素,并返回对应的节点
*/
private Node<T> findTargetNode(Node<T> node, T element) {
if (node == null) {
return null;
}
if (element.compareTo(node.data) == 0) {
return node;
} else if (element.compareTo(node.data) < 0) {
return findTargetNode(node.left, element);
} else {
return findTargetNode(node.right, element);
}
}
/**
* 查找节点的父节点
*/
private Node<T> findParentNode(T target) {
if (target == null || root == null || root.data == target) {
return null;
}
Node<T> cur = root;
while (cur != null) {
if (cur.left != null && cur.left.data == target) {
return cur;
}
if (cur.right != null && cur.right.data == target) {
return cur;
}
if (target.compareTo(cur.data) < 0) {
cur = cur.left;
} else {
cur = cur.right;
}
}
return null;
}
/**
* 查找右子树中的最小节点
*/
private Node<T> findMinNodeFromRight(Node<T> node) {
if (node.left == null) {
return node;
}
return findMinNodeFromRight(node.left);
}
/**
* 前序遍历
*/
@Override
public void preOrderTraversal() {
preOrderTraversal(root);
}
/**
* 前序遍历以 node 为根节点的子树
*/
private void preOrderTraversal(Node<T> node) {
if (node == null) {
return;
}
System.out.print(node.data + " ");
preOrderTraversal(node.left);
preOrderTraversal(node.right);
}
/**
* 中序遍历
*/
@Override
public void inOrderTraversal() {
inOrderTraversal(root);
}
/**
* 中序遍历以 node 为根节点的子树
*/
private void inOrderTraversal(Node<T> node) {
if (node == null) {
return;
}
inOrderTraversal(node.left);
System.out.print(node.data + " ");
inOrderTraversal(node.right);
}
/**
* 后序遍历
*/
@Override
public void postOrderTraversal() {
postOrderTraversal(root);
}
/**
* 后序遍历以 node 为根节点的子树
*/
private void postOrderTraversal(Node<T> node) {
if (node == null) {
return;
}
postOrderTraversal(node.left);
postOrderTraversal(node.right);
System.out.print(node.data + " ");
}
/**
* 获取节点数量
*/
@Override
public int size() {
return size;
}
}
```
注意:在 remove 方法中,如果要删除的节点既有左孩子,又有右孩子,那么需要找到右子树中的最小节点来替换当前节点,这个操作比较复杂。需要用到两个辅助方法:findMinNodeFromRight 和 removeMinNodeFromRight。
同时,为了实现 findParentNode 和 findMinNodeFromRight 方法,需要比较节点数据的大小,所以要让节点数据实现 Comparable 接口。
阅读全文