Java实现二分搜索树的示例代码

网友投稿 291 2022-08-19


Java实现二分搜索树的示例代码

目录1.概念2.重点操作3.完整代码

1.概念

a.是个二叉树(每个节点最多有两个子节点)

b.对于这棵树中的节点的节点值

左子树中的所有节点值 < 根节点 < 右子树的所有节点值

二分搜索树中一般不考虑值相等的情况(元素不重复)JDK中的搜索树就不存在相同的值(TreeMap-key)

最大特点:也是判断是否是搜索树的方法

对该树进行中序遍历,就可以得到一个升序集合0 1 2 3 4 5 6 7 8 9

在一个有序区间上进行二分查找的时间复杂度? logn不断将集合/2/2 / 2 ==1为止logN

logN =》联想到"树"

2.重点操作

当删除58时,此节点左右子树都不为空

Hibbard Deletion 1962

在BST中删除一个左右子树都存在的节点

找到当前以58为根节点的前驱或者后继节点作为删除后的新节点

前驱:在以58为根的BST中最后一个小于58的节点->53

后继:在以58为根的BST中第一个大于58的节点->59

当我们使用后继节点时,先连removeMin(root.right),在连root.left

TreeNode successor = findMin(root.right);

successor.right = removeMin(root.right);

successor.left = root.left;

3.完整代码

import java.util.NoSuchElementException;

/**

* 基于整型的

* 普通的二分搜索树

*/

public class BST {

private class TreeNode{

private int val;

private TreeNode left;

private TreeNode right;

public TreeNode(int val) {

this.val = val;

}

}

private int size;

private TreeNode root;

/**

* 向以root为根的BST中插入一个新的结点val

* @param val

*/

public void add(int val){

root = add(root,val);

}

private TreeNode add(TreeNode root, int val) {

if(root == null){

//创建一个新节点

TreeNode newNode = new TreeNode(val);

size++;

return newNode;

}

//左子树插入

if(val < root.val){

root.left = add(root.left,val);

}

//右子树插入

if(val > root.val){

root.right = add(root.right,val);

}

return root;

}

/**

* 判断当前以root为根的BST中是否包含了val

* @param val

* @return

*/

public boolean contains(int val){

return contains(root,val);

}

private boolean contains(TreeNode root, int val) {

if(root == null){

return false;

}

if(val == root.val){

//找到了

return true;

}else if(val < root.val){

//递归左子树查找

return contains(root.left,val);

}else{

//递归右子树查找

return contains(root.right,val);

}

}

/**

* 找到最小值

* @return

*/

public int findMin(){

//判空

if(root == null){

//抛出一个空指针异常

throw new NoSuchElementException("root is empty! cannot find min");

}

TreeNode minNode = findMin(root);

return minNode.val;

}

private TreeNode findMin(TreeNode root) {

//当此节点左子树为空,说明此节点是最小值

if(root.left == null){

return root;

}

//递归访问左子树

return findMin(root.left);

}

/**

* 找到最大值

* @return

*/

public int findMax(){

//判空

if(root == null){

throw new NoSuchElementException("root is empty! cannot find max");

}

TreeNode maxNode = findMax(root);

return maxNode.val;

}

private TreeNode findMax(TreeNode root) {

//当此节点右子树为空,说明此节点是最大值

if(root.right == null){

return root;

}

//递归访问右子树

return findMax(root.right);

}

/**

* 在当前BST中删除最小值节点,返回删除的最小值

* @return

*/

public int removeMin(){

int min =findMin();

root = removeMin(root);

return min;

}

private TreeNode removeMin(TreeNode root) {

if(root.left == null){

TreeNode right = root.right;

//找到最小值,删除节点

root = root.left = null;

size--;

return right;

}

root.left = removeMin(root.left);

return root;

}

/**

* 在当前BST中删除最大值节点,返回删除的最大值

* @return

*/

public int removeMax(){

int max = findMax();

root = removeMax(root);

return max;

}

//在当前以root为根的BST中删除最小值所在的节点,返回删除后的树根

private TreeNode removeMax(TreeNode root) {

if(root.right == null){

TreeNode right = root.right;

//找到最大值,删除节点

root = root.right = null;

size--;

return right;

}

root.right = findMax(root.right);

return root;

}

/**

* 在当前以root为根节点的BST中删除值为val的节点

* 返回删除后的新的根节点

* @return

*/

public void removeValue(int value){

root = removeValue(root,value);

}

private TreeNode removeValue(TreeNode root, int value) {

if(root == null){

throw new NoSuchElementException("root is empty! cannot find remove");

}else if(value < root.val){

root.left = removeValue(root.left,value);

return root;

}else if(value > root.val){

root.right = removeValue(root.right,value);

return root;

}else {

//此时value == root.value

if(root.left == null){

//删除最小数

TreeNode right = root.right;

root = root.right = null;

size--;

return right;

}

if(root.right == null){

//删除最大数

TreeNode left = root.left;

root = root.left =null;

size--;

return left;

}

//找到当前该删除节点的前驱或者后继节点作为删除后的新节点

//当我们使用后继节点时,先连removeMin(root.right),在连root.left

TreeNode successor = findMin(root.right);

successor.right = removeMin(root.right);

successor.left = root.left;

return successor;

}

}

@Override

public String toString() {

StringBuilder sb = new StringBuilder();

generateBSTString(root,0,sb);

return sb.toString();

}

//直观打印,可以看到树的深度

private void generateBSTString(TreeNode root, int height, StringBuilder sb) {

if(root == null){

sb.append(generateHeightString(height)).append("NULL\n");

RDVPW return;

}

sb.append(generateHeightString(height)).append(root.val).append("\n");

generateBSTString(root.left,height+1,sb);

generateBSTString(root.right,height+1,sb);

}

private String generateHeightString(int height) {

StringBuilder sb = new StringBuilder();

for (int i = 0; i < height; i++) {

sb.append("--");

}

return sb.toString();

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:RestTemplate如何通过HTTP Basic Auth认证示例说明
下一篇:使用HttpSessionListener监听器实战
相关文章

 发表评论

暂时没有评论,来抢沙发吧~