二叉查找树

我们所使用的数据结构有结点组成,结点所办韩的链接可以指向空(null)或者其他节点。在二叉树中,每个节点只能有一个父节点指向自己(只有一个例外,也就是根结点,它没有父结点),而且每个结点都只有左右两个链接,分别指向自己的左子结点和右子结点。尽管我们指向的是结点,但我们可以将每个链接看作指向了另一颗二叉树,而这棵树的根结点就是被指向的结点。因此我们可以将二叉树定义为一个空链接,或者是一个有左右两个链接的结点,每个链接都指向一颗子二叉树。

在这里插入图片描述

一颗二叉查找树每一个结点都含有一个Comparable的键且每个结点的键都大于其左子树中的任意结点的键而小于右子树的任意结点的键。

实现

public class BST<Key extends Comparable<Key>,Value> {

    private Node root;//二叉树的根节点

    private class Node{
        private Key key;//键
        private Value val;//值
        private Node left,right;//指向子树的链接
        private int N;//以该节点为根的子树

        public Node (Key key,Value val,int N){
            this.key = key;
            this.val = val;
            this.N = N;
        }
    }

    public int size(){
        return size(root);
    }

    private int size(Node x){
        if (x == null){
            return 0;
        }
        return x.N;
    }
}

上面的代码定义了二叉查找树的数据结构。和定义链表一样我们嵌套定义了一个私有类来表示二叉查找树的一个结点。每个结点都含有一个键,一个值,一条左链接,一条右链接和一个结点计数器。左链接指向一颗由小于该结点的所有键组成的二叉查找树,右连接指向一颗由大于该结点的所有键组成的二叉查找树。变量N给出了以该结点为根的子树的结点总数。

私有方法size()会将空链接的值当做0,这样我们就能保证一下公式对于二叉树中的任意结点x总是成立:
size(x) = size(x.left) + size(x.right) + 1

一颗二叉查找树代表了一组键(及其相应的值)的集合,而同一个集合可以用多颗不同的二叉查找树来表示。如果我们将一颗而查找树的所有键投影到一条直线上,保证一个结点的左子树中的键出现在他的左边,右子树中的键出现在他的右边,那么我们一定可以得到一条有序的键列。我们会利用二叉查找树的这种天生的灵活性,用多颗二叉查找树表示同一组有序的键来实现构建和使用二叉查找树的高效算法。

查找与插入

一般来说,查找有两种结构。如果包含该键的结点存在,我们的查找就命中了,然后返回相应的值。否则查找未命中。根据数据表示的递归结构我们马上就能得到,在二叉查找树中查找一个键的递归算法:如果树是空的,则查找未命中;如果被查找的键和根结点的键相等,查找命中,否则我们就(递归地)在适当的子树中继续查找。如果被查找的键较小就选择左子树,较大则选择右子树。

二叉树查找树的查找及插入实现如下:

public Value get(Key key) {
        return get(root, key);
    }

    private Value get(Node x, Key key) {
        if (x == null) {
            return null;
        }
        int cmp = key.compareTo(x.key);
        if (cmp < 0) {
            return get(x.left, key);
        } else if (cmp > 0) {
            return get(x.right, key);
        }
        return x.val;
    }

    public void put(Key key, Value val) {
        root = put(root, key, val);
    }

    private Node put(Node x, Key key, Value val) {
        if (x == null) {
            return new Node(key, val, 1);
        }
        int cmp = key.compareTo(x.key);
        if (cmp < 0) {
            x.left = put(x.left, key, val);
        } else if (cmp > 0) {
            x.right = put(x.right, key, val);
        } else {
            x.val = val;
        }
        x.N = size(x.left) + size(x.right) + 1;
        return x;
    }

上述代码实现了二叉查找树中的put()和get()方法,他们的实现都是通过递归完成的。

插入的逻辑和查找的逻辑很相似:如果树是空的,就返回一个含有该结点键值对的新结点;如果被查找的键小于根结点的键,我们会继续在左子树中插入该键,否则在右子树中插入该键。

分析

使用二叉查找树的运行时间取决于树的形状,而树的形状又取决于键被插入的先后顺序。在最好的情况下,一颗含有N个节点的树是完全平衡的,每条空链接和根结点的距离都是lgN。在最坏的情况下,搜索路径上可能有N个节点。

假设键的分布是随机的,可以看出:二叉查找树和快速排序几乎是“双胞胎”。树的根结点就是快速排序中的第一个切分元素(左侧的键都比他小,右侧的键都比他大),以此类推,这和快速排序算法中队子数组的递归排序完全对应。

最大键和最小键

如果根结点的左链接为空,那么一颗二叉查找树中的最小键就是根结点;如果左链接不为空,那么树中的最小键就是左子树中的最小键。找到最大键的方法也是类似的,只是变成查找右子树而已。

获取最小值方法实现如下:

 public Key min() {
        return min(root).key;
    }

    private Node min(Node x) {
        if (x.left == null) {
            return x;
        }
        return min(x.left);
    }

删除最大键和最小键

对于deleteMin(),我们要不断深入根结点的左子树中直到遇到一个空链接,然后将纸箱该结点的链接指向他的右子树(只需在递归中调用返回它的右链接即可)。此时已经没有任何链接指向要被删除的结点,因此他会被垃圾处理器清理掉。deleteMax()方法的实现和deleteMin()方法完全类似。

使用优化算法,以优化VMD算法的惩罚因子惩罚因子 (α) 和分解层数 (K)。 1、将量子粒子群优化(QPSO)算法与变分模态分解(VMD)算法结合 VMD算法背景: VMD算法是一种自适应信号分解算法,主要用于分解信号为不同频率带宽的模态。 VMD的关参数包括: 惩罚因子 α:控制带宽的限制。 分解层数 K:决定分解出的模态数。 QPSO算法背景: 量子粒子群优化(QPSO)是一种基于粒子群优化(PSO)的一种改进算法,通过量子行为模型增强全局搜索能力。 QPSO通过粒子的量子行为使其在搜索空间中不受位置限制,从而提高算法的收敛速度与全局优化能力。 任务: 使用QPSO优化VMD中的惩罚因子 α 和分解层数 K,以获得信号分解的最佳效果。 计划: 定义适应度函数:适应度函数根据VMD分解的效果来定义,通常使用重构信号的误差(例如均方误差、交叉熵等)来衡量分解的质量。 初始化QPSO粒子:定义粒子的位置和速度,表示 α 和 K 两个参数。初始化时需要在一个合理的范围内为每个粒子分配初始位置。 执行VMD分解:对每一组 α 和 K 参数,运行VMD算法分解信号。 更新QPSO粒子:使用QPSO算法更新粒子的状态,根据适应度函数调整粒子的搜索方向和位置。 迭代求解:重复QPSO的粒子更新步骤,直到满足终止条件(如适应度函数达到设定阈值,或最大迭代次数)。 输出优化结果:最终,QPSO算法会返回一个优化的 α 和 K,从而使VMD分解效果最佳。 2、将极光粒子(PLO)算法与变分模态分解(VMD)算法结合 PLO的优点与适用性 强大的全局搜索能力:PLO通过模拟极光粒子的运动,能够更高效地探索复杂的多峰优化问题,避免陷入局部最优。 鲁棒性强:PLO在面对高维、多模态问题时有较好的适应性,因此适合海上风电时间序列这种非线性、多噪声的数据。 应用场景:PLO适合用于优化VMD参数(α 和 K),并将其用于风电时间序列的预测任务。 进一步优化的建议 a. 实现更细致的PLO更新策略,优化极光粒子的运动模型。 b. 将PLO优化后的VMD应用于真实的海上风电数据,结合LSTM或XGBoost等模型进行风电功率预测。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值