Arrays 排序数组中插入的摊销时间是O(n),删除的摊销时间是O(1)?

Arrays 排序数组中插入的摊销时间是O(n),删除的摊销时间是O(1)?,arrays,algorithm,sorting,amortized-analysis,Arrays,Algorithm,Sorting,Amortized Analysis,我正在学习如何分析算法,我发现了“摊销时间”的符号。我发现了一些预定义的估计,如: -排序数组中插入的摊销时间为:O(n) 从排序数组中删除的摊销时间为:O(1) 谁能给我详细解释一下吗 方法是将一个名为deleted的布尔值与数组中的每个条目相关联。删除项目包括将deleted设置为true。当删除的项目太多时,请将其压缩。如果将压缩阈值设置为总大小的一小部分,则可以从达到压缩点所需的所有删除中支付压缩费用 这是一张草图。它不完整,但演示了插入和删除算法 class sorted_array

我正在学习如何分析算法,我发现了“摊销时间”的符号。我发现了一些预定义的估计,如:

-排序数组中插入的摊销时间为:O(n)

从排序数组中删除的摊销时间为:O(1)


谁能给我详细解释一下吗

方法是将一个名为
deleted
的布尔值与数组中的每个条目相关联。删除项目包括将
deleted
设置为true。当删除的项目太多时,请将其压缩。如果将压缩阈值设置为总大小的一小部分,则可以从达到压缩点所需的所有删除中支付压缩费用

这是一张草图。它不完整,但演示了插入和删除算法

class sorted_array
{
public:
    typedef std::vector<std::pair<int, bool>>::iterator iterator;

    iterator insert(int value)
    {
        auto item = std::make_pair(value, false);
        return vec.insert(std::lower_bound(vec.begin(), vec.end(), item), item);
    }

    void erase(iterator pos)
    {
        pos->second = true; // deleted = true
        deleted_count++;
        if (deleted_count * 2 > vec.size())
        {
           vec.erase(std::remove_if(vec.begin(), vec.end(),
                                    std::get<1, int, bool>), vec.end());
           deleted_count = 0;
        }
    }

private:
    size_t deleted_count = 0;
    std::vector<std::pair<int, bool>> vec;
}
类排序\u数组
{
公众:
typedef std::vector::迭代器迭代器;
迭代器插入(int值)
{
自动项=std::make_pair(值,false);
返回vec.insert(标准::下限(vec.begin(),vec.end(),item),item);
}
无效擦除(迭代器位置)
{
pos->second=true;//已删除=true
已删除_count++;
如果(已删除\u count*2>向量大小())
{
向量擦除(std::remove_if(vec.begin(),vec.end(),
std::get),vec.end();
已删除的\u计数=0;
}
}
私人:
大小\u t已删除\u计数=0;
std::vec;
}
插入像往常一样是O(n)。插入元素时,我们还将其标记为未删除

要删除一个元素,我们只需将其标记为已删除并存入两个贷方即可

当向量中超过一半的元素被删除时,这意味着我们至少拥有与向量中元素相同的信用。这意味着我们有能力运行O(n)压缩

要查找元素,请运行传统的二进制搜索,然后跳过已删除的元素。由于最多有一半的元素被删除,因此二进制搜索最多在2n个元素上运行,这意味着它以O(log2n)=O(logn)步运行。在二进制搜索完成后,向前跳过已删除的项目会有一点额外的成本,但是数据结构中的一些更聪明的方法可以将其降低到一个常数。(作为练习离开。)


类似地,迭代集合最多需要2n个步骤(因为最多有一半的元素被删除),这仍然是O(n)。

思想是将数组中的每个条目与一个名为
deleted
的布尔值相关联。删除项目包括将
deleted
设置为true。当删除的项目太多时,请将其压缩。如果将压缩阈值设置为总大小的一小部分,则可以从达到压缩点所需的所有删除中支付压缩费用

这是一张草图。它不完整,但演示了插入和删除算法

class sorted_array
{
public:
    typedef std::vector<std::pair<int, bool>>::iterator iterator;

    iterator insert(int value)
    {
        auto item = std::make_pair(value, false);
        return vec.insert(std::lower_bound(vec.begin(), vec.end(), item), item);
    }

    void erase(iterator pos)
    {
        pos->second = true; // deleted = true
        deleted_count++;
        if (deleted_count * 2 > vec.size())
        {
           vec.erase(std::remove_if(vec.begin(), vec.end(),
                                    std::get<1, int, bool>), vec.end());
           deleted_count = 0;
        }
    }

private:
    size_t deleted_count = 0;
    std::vector<std::pair<int, bool>> vec;
}
类排序\u数组
{
公众:
typedef std::vector::迭代器迭代器;
迭代器插入(int值)
{
自动项=std::make_pair(值,false);
返回vec.insert(标准::下限(vec.begin(),vec.end(),item),item);
}
无效擦除(迭代器位置)
{
pos->second=true;//已删除=true
已删除_count++;
如果(已删除\u count*2>向量大小())
{
向量擦除(std::remove_if(vec.begin(),vec.end(),
std::get),vec.end();
已删除的\u计数=0;
}
}
私人:
大小\u t已删除\u计数=0;
std::vec;
}
插入像往常一样是O(n)。插入元素时,我们还将其标记为未删除

要删除一个元素,我们只需将其标记为已删除并存入两个贷方即可

当向量中超过一半的元素被删除时,这意味着我们至少拥有与向量中元素相同的信用。这意味着我们有能力运行O(n)压缩

要查找元素,请运行传统的二进制搜索,然后跳过已删除的元素。由于最多有一半的元素被删除,因此二进制搜索最多在2n个元素上运行,这意味着它以O(log2n)=O(logn)步运行。在二进制搜索完成后,向前跳过已删除的项目会有一点额外的成本,但是数据结构中的一些更聪明的方法可以将其降低到一个常数。(作为练习离开。)


类似地,对集合进行迭代最多需要2n步(因为最多有一半的元素被删除),这仍然是O(n)。

可能重复的No我不需要知道什么是摊销时间,我想知道从哪里得到的结果O(n)用于插入,O(1)用于删除。谢谢如果你已经知道摊销时间是什么意思,你可能会想通过你的问题来明确你想知道什么,因为它看起来好像你不知道它的意思。如果您知道摊销时间的含义,那么理解给定的big-O值会有什么困难?从排序数组中删除的摊销时间不是O(1)(通常)。您可能希望提供与这些值一起使用的算法的任何描述,以防存在允许摊销O(1)的特定约束。@Dukeling您能否提供删除成本O(1)的算法的任何示例?可能重复的否我不需要知道摊销时间,我想知道,从哪里我们得到了插入的O(n)和删除的O(1)的结果。谢谢如果你已经知道摊销时间是什么意思,你可能会想通过你的问题来明确你想知道什么,因为它看起来好像你不知道它的意思。如果您知道摊销时间的含义,那么理解给定的big-O值会有什么困难?从排序数组中删除的摊销时间不是O(1)(通常)。您可能需要提供任何关于