PS:这里推荐一个看生成二叉树的工具网站:
点我就可以
定义:
二叉搜索树的意思就是 左孩子 < 父节点 < 右孩子
可以打开这个网址一边看动画,一边看代码,方便理解。
那,话不多说,下面进入正题,下面利用递归的方式实现泛型二叉搜索树。支持任意可比较的数据类型。
1.首先先编写一个二叉树结点。
/**
* 二叉搜索树
*
* 1.支持任意可比较的数据类型
* 2.也可以通过重写object类的
* compareTo方法实现
*
* @author 137***81
*
* @param <T>
*/
public class Node <T extends Comparable<T>>{
T data;
Node<T> leftChild;
Node<T> rightChild;
public Node(T data) {
this.data = data;
}
public Node(T data , Node<T> leftChild, Node<T> rightChild) {
this.data = data;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
}
2.在编写一个二叉搜索树的类
public class SearchTree<T extends Comparable<T>>{
//根节点
Node<T> root;
/**
* 向用户暴露插入方法
* @param data 插入的数据
* @throws Exception
*/
public void insert(T data) throws Exception {
if(root == null) root = new Node<T>(data,null,null);
else addElement(new Node<T>(data) ,root);
}
/**
* 向用户暴露查询方法
* @param data 搜索的数据
* @return 没查到为null
* @throws Exception
*/
public Node<T> query(T data) throws Exception{
if(root == null) throw new Exception("root is null");
return query(data , root);
}
/**
* 向用户暴露删除方法
* @param data 要删除的数据
* @return 删除成功返回true,否则false
* @throws Exception
*/
public void delete(T data) throws Exception{
if(root == null) throw new Exception("root is null");
deleteNode(root,data);
}
/**
* 向用户暴露查找最小节点的方法
* @param node
* @return
*/
public Node<T> findMin() throws Exception{
if(root == null) throw new Exception("root is null");
return findMin(root);
}
/**
* 判断是否是二叉搜索树
* @return
*/
public boolean isSearchTree() {
return isSearchTree(root,null,null);
}
//私有化封装方法
private Node<T> query(T data , Node<T> root) {
if(root == null) return null;
int compareResult = data.compareTo(root.data);
if(compareResult > 0)
return query(data, root.rightChild);
else if(compareResult < 0)
return query(data, root.leftChild);
return root;
}
//私有化封装方法
private Node<T> addElement(Node<T> node , Node<T> root) throws Exception {
if(root == null) return node;
int compareResult = node.data.compareTo(root.data);
if(compareResult > 0)
root.rightChild = addElement(node, root.rightChild);
else if(compareResult < 0)
root.leftChild = addElement(node, root.leftChild);
else throw new Exception("data is Exist!");
return root;
}
//私有化封装方法
private Node<T> deleteNode(Node<T> root, T key) {
if (root == null) {
return null;
}
int compareResult = key.compareTo(root.data);
if (compareResult < 0) {
// 待删除节点在左子树中
root.leftChild = deleteNode(root.leftChild, key);
return root;
} else if (compareResult > 0) {
// 待删除节点在右子树中
root.rightChild = deleteNode(root.rightChild, key);
return root;
} else {
if (root.leftChild == null) {
// 返回右子树作为新的根
return root.rightChild;
} else if (root.rightChild == null) {
// 返回左子树作为新的根
return root.leftChild;
} else {
// 左右子树都存在,返回后继节点(右子树最左叶子)作为新的根
Node<T> successor = min(root.rightChild);
successor.rightChild = deleteMin(root.rightChild);
successor.leftChild = root.leftChild;
return successor;
}
}
}
/**
* 返回最小节点
* @param node
* @return
*/
private Node<T> min(Node<T> node) {
if (node.leftChild == null) {
return node;
}
return min(node.leftChild);
}
/**
* 返回最小节点的右孩子
* @param node
* @return
*/
private Node<T> deleteMin(Node<T> node) {
if (node.leftChild == null) {
return node.rightChild;
}
node.leftChild = deleteMin(node.leftChild);
return node;
}
/**
* 找到最小值
* @param node 根节点
* @return 返回最小的结点
*/
public Node<T> findMin(Node<T> root){
if(root == null) return null;
else if(root.leftChild == null)
return root;
return findMin(root.leftChild);
}
//前序遍历
public void preOrder(Node<T> root) {
if (root == null)
return;
System.out.print(root.data + " ");
preOrder(root.leftChild);
preOrder(root.rightChild);
}
/**
* 二叉搜索的前序遍历就是 【升序】
* @param root
*/
public void midOrder(Node<T> root) {
if (root == null)
return;
midOrder(root.leftChild);
System.out.print(root.data + " ");
midOrder(root.rightChild);
}
/**
* 判断是否是二叉搜索树
* @param root
* @param minNode
* @param maxNode
* @return
*/
private boolean isSearchTree(Node<T> root, Node<T> minNode,Node<T> maxNode) {
if(root == null) return true;
if((minNode!=null&&root.data.compareTo(minNode.data) <= 0)||
(maxNode!=null&&root.data.compareTo(maxNode.data) >= 0)) {
return false;
}
return isSearchTree(root.leftChild,null,root)&&isSearchTree(root.rightChild,root,null);
}
}
3.接下来就是调用使用它了
public static void main(String[] args) throws Exception{
SearchTree<Integer> tree = new SearchTree<>();
tree.insert(33);
tree.insert(80);
tree.insert(20);
tree.insert(100);
tree.insert(49);
tree.insert(3);
//中序遍历
tree.midOrder(tree.root);
System.out.println();
//query
Node<Integer> node = tree.query(20);
if(node != null) {
System.out.println("found one! value is:" + node.data);
}else {
System.out.println("opps ! not found");
}
//findMin
Node<Integer> minNode = tree.findMin();
System.out.println("found one! minNode is:" + minNode.data);
//delete
tree.delete(80);
//验证一下是否删除成功
tree.midOrder(tree.root);
System.out.println();
System.out.println(tree.isSearchTree()?"true":"false");
}
运行结果如下:
PS:纯属个人理解,希望指正!