保持排序序列,不包含小于谓词

Keeping sorted sequence without a less-than predicate

本文关键字:包含 小于 谓词 排序      更新时间:2023-10-16

我希望保留一个排序的项目队列,在那里我希望能够弹出具有最低值的项目(有点像std::priority_queue)。项值是连续的并且不断增加。但是,这些项没有定义小于比较,它们只有is-previousis-next谓词(其中A is-previous B==B is-next A),它们还支持++--

我想知道是否有任何算法可以基于这样的谓词对值进行(部分)排序?或者,有没有更好的方法来跟踪这样的队列?

这个问题发生在模运算中——项目由整数指定,但由于模运算,小于和大于失去了意义,不能再用于排序。

选择的语言是C++,但我想我可以移植大多数合理的语言。

编辑

对所有试图回答的人来说,在编写示例代码时,我意识到最初的问题格式不正确。这真的很尴尬,但我想强调的是,你的时间没有浪费,因为我为此汗流浃背了一个小时,10分钟后我意识到这是多么的错误。不管怎样,这就是我想要的行为:

template <class T>
class OrderedQueue {
    std::vector<T> storage;
    T next;
public:
    OrderedQueue(T lowest_value = T())
        :next(lowest_value)
    {}
    void Push(T t)
    {
        storage.push_back(t);
    }
    T Pop()
    {
        std::vector<T>::iterator it = std::find(storage.begin(), storage.end(), next);
        if(it == storage.end())
            throw std::runtime_error("no such element");
        T value = *it;
        storage.erase(it);
        ++ next;
        return value;
    }
};

我的问题是Pop()O(N)。有没有一种方法可以让它更快,使用Is prev和Is next谓词?

我的问题是Pop()取O(N)。有没有一种方法可以让它更快,使用Is prev和Is next谓词?

您需要提供一种方法来获得密钥的实际模整数表示,比如Integer(x)。则CCD_ 11和CCD_。

如果您有整数和模数M,请使用一个双链表数组(std::list<T> queues[M]),将Push(x)实现为queues[Integer(x)].push_back(x),并将Pop实现为

size_t i = Integer(next);
// check for existence, raise if necessary
T r = queues[i].front();
queues[i].pop_front();
return r;

如果M很大,并且您希望大多数队列在大多数时间都是空的,那么您可以使用std::unordered_map<size_t, std::list<T>>来获得相同的复杂性,但节省空间。

也可以使用CCD_ 20;这两种操作只提供了摊销的恒定时间,但在实践中可能会快得多。

在C++中,您的类型不需要定义operator<来进行排序或在关联容器中使用。容器和算法可以采用执行比较的谓词。例如,使用is_pred作为谓词对向量进行排序(假设它已经是函数对象或纯函数):

std::sort(v.begin(), v.end(), is_pred);

如果没有,您可以编写自己的函子适配器或lambda:

std::sort(v.begin(), v.end(), [](T const& lhs, T const& rhs) {
             return apply_is_pred_predicate(lhs,rhs)
          });

这里的要求是关系是prev必须是一个严格的弱序。