二分搜索树实现

二分搜索树删除任意节点

只有右孩子的节点

与删除最小元素的情况相同    

只有左孩子的节点

与删除最大元素的情况相同

叶子节点

即可以当做只有左孩子的节点也可以当做只有右孩子的节点

既有左孩子又有右孩子的节点

待删除的节点记作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;
        }
    }

}
内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值