Есть ли интересные алгоритмы, использующие как стек, так и очередь (deque) ADT?

мы часто используем стеки или очереди в наших алгоритмах, но есть ли случаи, когда мы используем дважды связанный список для реализации и стек и очередь в алгоритме? Например, на одном этапе мы помещаем () 6 элементов в стек, pop() 2 элемента, а затем dequeue () остальные элементы (4) из хвоста дважды связанного списка. То, что я ищу, - это неясные, интересные алгоритмы, которые реализуют что-то в этом методе или даже более странное. Псевдокод, ссылки и объяснения были бы кстати.

4 ответов


на алгоритм Melkman (для вычисления выпуклой оболочки простого многоугольника цепи в линейном времени) использует двусторонняя очередь (a.к. а очереди) для хранения инкрементного корпуса для уже обработанных вершин.

Input: a simple polyline W with n vertices V[i]

    Put first 3 vertices onto deque D so that:
    a) 3rd vertex V[2] is at bottom and top of D
    b) on D they form a counterclockwise (ccw) triangle

    While there are more polyline vertices of W to process
    Get the next vertex V[i]
    {
        Note that:
        a) D is the convex hull of already processed vertices
        b) D[bot] = D[top] = the last vertex added to D

        // Test if V[i] is inside D (as a polygon)
        If V[i] is left of D[bot]D[bot+1] and D[top-1]D[top]
            Skip V[i] and Continue with the next vertex

        // Get the tangent to the bottom
        While V[i] is right of D[bot]D[bot+1]
            Remove D[bot] from the bottom of D
        Insert V[i] at the bottom of D

        // Get the tangent to the top
        While V[i] is right of D[top-1]D[top]
            Pop D[top] from the top of D
        Push V[i] onto the top of D
    }

    Output: D = the ccw convex hull of W.

источник:http://softsurfer.com/Archive/algorithm_0203/algorithm_0203.htm

Джо Митчелл: алгоритм выпуклой оболочки Мелкмана (PDF)


эта структура называется Deque, то есть очередь, где элементы могут быть добавлены или удалены из головы или хвоста. Подробнее в 1.


Я не уверен, подходит ли это, но вы можете использовать двухсторонний приоритет очередь для применения quicksort к файлу, слишком большому, чтобы поместиться в памяти. Идея состоит в том, что в обычной quicksort вы выбираете элемент в качестве оси, а затем разделяете элементы на три группы - элементы меньше оси, элементы, равные оси, и элементы, большие оси. Если вы не можете поместить все элементы в память сразу, вы можете адаптировать это решение следующим образом. Вместо выбрав один элемент в качестве оси, вместо этого выберите огромное количество элементов (столько, сколько вы можете поместить в ОЗУ, скажем) и вставьте их в очередь с двойным приоритетом. Затем сканируйте остальные элементы по одному. Если элемент меньше наименьшего элемента двусторонней очереди приоритетов, поместите его в группу элементов, меньших, чем все оси. Если он больше, чем самый большой элемент очереди приоритетов, то поместите его в группу элементов больше, чем стержни. В противном случае вставьте элемент в очередь с двойным приоритетом, а затем удалите из очереди самый маленький или самый большой элемент и поместите его в соответствующую группу. Как только вы закончите это делать, вы разделите элементы на три части - группу небольших элементов, которые затем могут быть рекурсивно отсортированы, группу элементов в середине, которые теперь полностью отсортированы (так как если вы удалите их все из двусторонней очереди приоритетов, они будут извлечены в сортированном виде order), и группа элементов больше, чем средние элементы, которые также могут быть отсортированы.

для получения дополнительной информации об этом алгоритме и двойных очередях приоритетов в целом, рассмотрите вопрос о этой ссылке в главе на эту тему.


мы можем изменить ширину первого поиска (который обычно используется для поиска кратчайших путей в графе с 1-взвешенными ребрами) для работы с 0-1 графами (т. е. графом с ребрами 0 и 1 Весов). Мы можем сделать это следующим образом: когда мы использовали 1-ребро, мы добавляем вершину назад, а когда мы используем 0-ребро, мы добавляем вершину в начало.