Сортування за допомогою стеків лише для читання


14

Розглянемо наступне налаштування:

  • нам дається стек який містить n елементів.sn
  • ми можемо використовувати постійну кількість додаткових стеків.O(1)
  • ми можемо застосувати наступні операції до цих стеків:
    1. перевірити, чи стек порожній,
    2. порівняйте основні елементи двох стеків,
    3. видаліть верхній елемент із стека,
    4. надрукувати верхній елемент у стеці,
    5. скопіюйте верхній елемент стека в інший стек,
    6. скопіюйте вміст одного стека в інший стек.

Зауважте, що це єдині дозволені операції. Ми не можемо поміняти елементи, і нам заборонено натискати будь-який елемент на будь-який із стеків, за винятком копіювання верхнього елемента в стек (після чого попередній вміст цільового стеку відкидається, і він буде містити лише скопійований елемент) .

Ось алгоритм сортування стеків за допомогою порівнянь :O(n2)

last := empty
for i from 1 to n
  min := empty
  w := s
  while w is not empty
    if w.top > last and w.top < min
      min := w.top
    delete w.top
  print min
  last := min

Чи можемо ми зробити краще?

Чи існує програма, яка друкує відсортований список елементів у стеках, використовуючи лише ?О(нжурналн)


2
Здається, що регістри поводяться як стеки? Це здається, що ви говорите про операції push і pop. Це ваші запитання? Як би ви сортували стек, використовуючи кілька стеків та операцій стека?
AturSams

2
За допомогою регістрів ви можете: просто помістити кожне число в один регістр ( O ( n ) ), а потім застосувати звичайний алгоритм сортування ( O ( n lg n ) ). nO(n)O(nlgn)
Каве

1
Ви хочете використовувати регістри ? Інакше проблема тривілізується, як коментує Каве. O(1)
Yuval Filmus

1
Будь ласка. Я думав, що нам дають ряд стеків, а не один, я це виправлю.
Каве

2
@akappa, ви впевнені, що їх можна використовувати в цьому баченні? Ми не можемо зберегти будь-яку довільну втрату розміру більше 1. Чи не потрібно зберігати відсортовані блоки?
Каве

Відповіді:


1

Я думаю, що зараз можу продемонструвати нетривіальну нижню межу. Ідея полягає в тому, щоб реалізувати будь-яку таку програму з сімейством програм розгалуження порівняння. Припущення "лише для читання" означає, що наше сімейство програм розгалуження використовує мало, тобто простору. Потім застосуємо нижню межу S T = Ω ( n 2 ), доведену Бородіном та ін. в "Часово-космічний компроміс для сортування на непомітних машинах". Це дає нам нижню межу на час n 2 / log n .O(logn)ST=Ω(n2)n2/logn

Трохи детальніше: Ми можемо не відмовитися від операції 5 вище. Якщо говорити, якщо ми вже можемо порівняти заголовки двох списків та надрукувати заголовки списку, тоді нам не потрібно виділяти голову списку на певний реєстр. Припускаючи це, ми бачимо, що кожен реєстр в машині зберігає лише останню підрядку вводу.

Припустимо, у нашій програмі регістрів є рядки коду та k регістри, X 1 , , X k .kX1,,Xk

Виправити . Побудуємо програму порівняння розгалуження для рядків довжиною n наступним чином. Створіть вузол для кожного кортежа ( i , d 1 , , d k ), де 1 i і 0 d 1 , , d kn . Ідея полягає в тому, що обчислення в машині реєстрації відповідають шляхам в програмі розгалуження, і ми знаходимося у вузлі ( i , d 1 , nn(i,d1,,dk)1i0d1,,dkn. Тепер ми повинні визначити спрямовані краї програми розгалуження(i,d1,,dk)якщо ми знаходимося в рядку в машині регістра, а довжина рядка, що зберігається в X i, є d iiXidi

Якщо рядок i має форму

якщо то goto i 1 else goto i 2Xu<Xvi1i2

то для всіх , вузол ( i , d 1 , , d k ) позначається, порівнюючи d u -th та d v -th елемент введення та маючи “справжній” край перейти до ( i 1 , d 1 , ... , d k ) , а "хибний" край до ( i 2 , d 1 , ... , d kd1,,dk(i,d1,,dk)dudv(i1,d1,,dk) .(i2,d1,,dk)

Якщо рядок має формуi

, пряма лінія i X1tail(X2)i

то є стрілка від будь-якого вузла до ( i , d 2 - 1 , , d k ) .(i,d1,,dk)(i,d21,,dk)

Якщо рядок має формуi

print(head(Xu))i

then there is an arrow from any node (i,d1,,dk) to (i,d1,,dk) which is labelled by the du-th node of the input.

Hopefully these examples make it clear how I intend to construct my branching program. When all is said and done, this branching program has at most nk nodes, so it has space O(logn)


0

Are you able to count elements? Then, I think, there is a fairly easy Mergesort implementation. If you were able to put additional symbols on the stack you could solve it with 3 stacks like this:

If we have only one element, the list is already sorted. Now assume we have already sorted the top half of the stack. We can copy the top half (in reverse order) to the second stack and place a separation symbol on top of it. Now we have again 3 Stacks (since we can ignore the already sorted symbols below the separation symbol) and can sort the lower half. Finally we can copy the sorted lower half to a third stack in reverse order and merge both halfs back to the original stack.

All operations cost linear time, therefore we have sorted the list in O(nlogn)

(Note, that we need stacks of size nlogn because of the separation symbols, but this can be easily corrected by using another stack)


Since you can't put new elements on the stack you may get problems at the separation points. To solve this you may do the following with some additional stacks:

Copy the top n2logn elements to an additional stack, then proceed with the remaining elements as before. Now you know exactly the number of elements you need to consider in each step and therefore don't need any separation symbols.

Finally repeat the procedure with the additional elements at most logn times and merge them to the original stack in linear time. Sorting the stacks costs, for some constant c, at most cnlogn+cn2logn2+cn4logn4+ ...=O(nlogn) time, while merging costs an additional O(nlogn).


I'm not sure I understand. How can we, for example, copy the top half on the stack in reverse order onto another stack when we can never push any element onto any stack?
Siddharth

We can not push any new element to a stack, but according to 5 we are able to push the top element of one stack to another. So copying the stack in reverse order requires at most linear time. So I suppose, that was not what you were asking for?
cero

You can't push anything on top of other items as explained in the question.
Kaveh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.