简体   繁体   English

是否有 C++ function 对 std::stack 进行排序?

[英]Is there a C++ function to sort a std::stack?

I have a std::stack in my code and I need to sort it.我的代码中有一个std::stack ,我需要对其进行排序。 Is there any built in function to do this?有没有内置的 function 可以做到这一点? As std::stack does not have std::end .由于std::stack没有std::end Can I use std::sort or would I have to go to the same old approach of using an auxiliary stack to sort the original stack?我可以使用std::sort还是必须 go 以使用辅助堆栈对原始堆栈进行排序的相同旧方法?

A std::stack is not a container, but a container adapter. std::stack不是容器,而是容器适配器。

As such, given it's intended semantics --因此,鉴于它的预期语义——

acts as a wrapper to the underlying container - only a specific set of functions is provided.充当底层容器的包装器 - 仅提供一组特定的功能。

-- it is a feature that you cannot sort it. ——这是一个你无法对其进行排序的功能。

Since the constructor copies any given container into the stack, the only way to directly sort the stack object would be to sort the underlying container member object:由于构造函数将任何给定容器复制到堆栈中,直接对堆栈 object 进行排序的唯一方法是对底层容器成员 object 进行排序:

Member objects成员对象

Container c the underlying container (protected member object) Container c底层容器(受保护的成员对象)

And to do that you would need to derive a new custom type from stack, with all the headaches deriving from a std container class involves.要做到这一点,您需要从堆栈中派生一个新的自定义类型,所有令人头疼的问题都源自 class 涉及的标准容器。

There could have been a std::stack::sort template using two auxiliary stacks and polyphase merge sort (time complexity O(n log(n)), see below), or the template could have been implemented based on the underlying container type: std::deque, std::list, or std::vector, since the container type can be specified for std::stack, such as:可能有一个 std::stack::sort 模板使用两个辅助堆栈和多相合并排序(时间复杂度 O(n log(n)),见下文),或者该模板可能已经基于底层容器类型实现: std::deque、std::list 或 std::vector,因为可以为 std::stack 指定容器类型,例如:

    std::stack <int, std::vector<int>> mystack;

std::sort can be used for std::deque or std::vector (both have random access iterators), and std::list::sort for std::list. std::sort 可用于 std::deque 或 std::vector(两者都有随机访问迭代器),而 std::list::sort 可用于 std::list。 I don't know if other container types or custom container types are allowed for std::stack;我不知道 std::stack 是否允许其他容器类型或自定义容器类型; if allowed, this would present an issue for trying to create a std::stack::sort based on the container type.如果允许,这将导致尝试基于容器类型创建 std::stack::sort 的问题。

using an auxiliary stack to sort the original stack使用辅助堆栈对原始堆栈进行排序

A stack sort with one auxiliary stack has O(n^2) time complexity.具有一个辅助堆栈的堆栈排序具有 O(n^2) 时间复杂度。 A stack sort with two auxiliary stacks, based on polyphase merge sort, has O(n log(n)) time complexity, but the code is complex.具有两个辅助堆栈的堆栈排序,基于多相归并排序,具有 O(n log(n)) 时间复杂度,但代码复杂。 It would be faster to move the stack to an array or vector, sort the array or vector, then create a new sorted stack.将堆栈移动到数组或向量,对数组或向量进行排序,然后创建一个新的排序堆栈会更快。

If you're curious about a polyphase merge sort for 3 stacks (the original and 2 auxiliaries), I wrote examples linked to below.如果您对 3 个堆栈(原始堆栈和 2 个辅助堆栈)的多相合并排序感到好奇,我编写了链接到下面的示例。 These use a custom stack container based on an array, and are about as fast as a standard merge sort on array, but require 2 temporary stacks.这些使用基于数组的自定义堆栈容器,并且与数组上的标准合并排序一样快,但需要 2 个临时堆栈。

A long time ago, polyphase merge sorts were used for tape drives.很久以前,多相合并排序被用于磁带驱动器。 Some tape drives could read backwards, to avoid rewind times, essentially making them stack like containers (write forwards, read backwards).一些磁带驱动器可以向后读取,以避免倒带时间,本质上使它们像容器一样堆叠(向前写入,向后读取)。 With tape drives, file marks or records of different size could be used to indicate end of run, eliminating the need to keep track of run boundaries with the code.对于磁带驱动器,可以使用不同大小的文件标记或记录来指示运行结束,从而无需跟踪代码的运行边界。 Many of the advanced versions of commercial polyphase merge sort programs were proprietary, and the knowledge essentially lost over time as tape sorts faded away into history.许多商业多相归并排序程序的高级版本是专有的,随着磁带排序逐渐消失在历史中,这些知识基本上随着时间的推移而丢失。

https://stackoverflow.com/a/38419908/3282056 https://stackoverflow.com/a/38419908/3282056

template <class T, class U, class Compare>
void sort_stack(std::stack<T,U> &stack, Compare comp)
{
    std::vector<T> tmp_container;
    tmp_container.reserve(stack.size());
    while(!stack.empty())
    {
        tmp_container.push_back(std::move(stack.top()));
        stack.pop();
    }
    std::sort(tmp_container.begin(), tmp_container.end(), comp);
    for(auto it:tmp_container)
    {
        stack.push(std::move(it));
    }
}
template <class T, class U>
void sort_stack(std::stack<T,U> &stack)
{
    sort_stack(stack, std::less<T>());
}

As far as I know, there is no way to sort stack in-place.据我所知,没有办法就地对堆栈进行排序。 But one workaround is using additional space.但一种解决方法是使用额外的空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM