Classificação usando pilhas somente leitura

14

Considere a seguinte configuração:

  • nos é dada uma pilha s que contém n itens.
  • podemos usar um número constante O(1)de pilhas extras.
  • podemos aplicar as seguintes operações nessas pilhas:
    1. verifique se uma pilha está vazia,
    2. compare os itens principais de duas pilhas,
    3. exclua o item superior em uma pilha,
    4. imprima o item superior em uma pilha,
    5. copie o item superior de uma pilha para outra pilha,
    6. copie o conteúdo de uma pilha para outra pilha.

Observe que essas são as únicas operações permitidas. Não podemos trocar itens e não temos permissão para enviar nenhum item para nenhuma das pilhas, com exceção de copiar o item superior em uma pilha (após o qual o conteúdo anterior da pilha de destino é descartado e conterá apenas o item copiado) .

Aqui está um algoritmo para classificar as pilhas com comparações de :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

Podemos fazer melhor?

Existe um programa que imprima a lista classificada dos itens nas pilhas usando apenas comparações ?O(nlogn)

Siddharth
fonte
2
Parece que os registros se comportam como pilhas? Parece que você está falando sobre operações push e pop. Essas são suas perguntas? Como você classificaria uma pilha usando várias pilhas e operações de pilha?
AturSams
2
Com registros, você pode: basta colocar todos os números em um registro ( O ( n ) ) e aplicar um algoritmo de classificação usual ( O ( n lg n ) ). nO(n)O(nlgn)
Kaveh
1
Deseja usar registradores? Caso contrário, o problema banaliza, como comentado por Kaveh. O(1)
Yuval Filmus
1
Você é bem vindo. Eu pensei que recebemos várias pilhas, não apenas uma, eu vou consertar.
22414 Kaveh
2
@akappa, você tem certeza de que pode ser usado nessa visão? Não podemos manter nenhuma perda arbitrária de tamanho maior que 1. Você não precisa armazenar os blocos classificados?
28414 Kaveh

Respostas:

1

Acho que agora posso demonstrar um limite inferior não trivial. A idéia é implementar qualquer programa com uma família de programas de comparação de ramificações. A suposição `` somente leitura '' significa que nossa família de programas de ramificação usa pouco espaço, isto é, . Em seguida, aplicamos o limite inferior S T = Ω ( n 2 ) comprovado por Borodin et al. em "Uma troca de tempo e espaço para classificação em máquinas não esquecidas". Isso nos dá um limite inferior de n 2 / log n para o tempo.O(registron)ST=Ω(n2)n2/registron

Um pouco mais detalhadamente: podemos dispensar a operação 5 acima. Em termos gerais, se já podemos comparar os cabeçalhos de duas listas e imprimir o cabeçalho de uma lista, não há necessidade de isolar o cabeçalho de uma lista em um registro específico. Supondo isso, vemos que todo registro na máquina apenas armazena uma substring final da entrada.

Suponha que nosso programa de registro tenha linhas de código ek registradores, X 1 , , X k .kX1,...,Xk

Fix . Construímos o programa de ramificação de comparação para cadeias de comprimento n da seguinte maneira. Crie um nó para cada tupla ( i , d 1 , , d k ) em que 1 i e 0 d 1 , , d kn . A idéia é que os cálculos na máquina de registro correspondam aos caminhos no programa de ramificação, e estamos no nó ( i , d 1 , , dnn(Eu,d1,...,dk)1Eu0 0d1,...,dkn se estamos na linha i na máquina registradora e o comprimento da string armazenada em X i é d i . Agora, temos que definir as arestas direcionadas do programa de ramificação(Eu,d1,...,dk)EuXEudEu

Se a linha tiver a formaEu

Se Then GoTo i 1 pessoa Goto i 2Xvocê<XvEu1Eu2

então, para todo o nó ( i , d 1 , , d k ) é rotulado comparando-se o elemento d u -th e d v -th da entrada e fazendo com que a borda "true" vá para ( i 1 , d 1 , d1,...,dk(Eu,d1,...,dk)dvocêdv e a aresta "falsa" para ( i 2 , d 1 , , d k(Eu1,d1,...,dk) .(Eu2,d1,...,dk)

Eu

X1tumaEueu(X2)Eu

existe uma seta de qualquer nó para ((Eu,d1,...,dk)(Eu,d2-1,...,dk)

Eu

prEunt(heumad(Xvocê))Eu

(Eu,d1,...,dk)(Eu,d1,...,dk)dvocê

nkO(registron)

Siddharth
fonte
0

Você é capaz de contar elementos? Acho que existe uma implementação bastante fácil do Mergesort. Se você pudesse colocar símbolos adicionais na pilha, poderia resolvê-lo com 3 pilhas como esta:

Se tivermos apenas um elemento, a lista já estará classificada. Agora suponha que já classificamos a metade superior da pilha. Podemos copiar a metade superior (em ordem inversa) para a segunda pilha e colocar um símbolo de separação em cima dela. Agora, temos novamente 3 pilhas (já que podemos ignorar os símbolos já classificados abaixo do símbolo de separação) e podemos classificar a metade inferior. Finalmente, podemos copiar a metade inferior classificada para uma terceira pilha na ordem inversa e mesclar as duas metades de volta à pilha original.

Todas as operações custam tempo linear, portanto, classificamos a lista em O(nregistron)

nregistron


Como você não pode colocar novos elementos na pilha, pode haver problemas nos pontos de separação. Para resolver isso, você pode fazer o seguinte com algumas pilhas adicionais:

n-2registron

registronccnregistron+cn2registron2+cn4registron4+ ...=O(nregistron)O(nregistron)

cero
fonte
Eu não tenho certeza se entendi. Como podemos, por exemplo, copiar a metade superior da pilha na ordem inversa para outra, quando nunca podemos inserir nenhum elemento em nenhuma pilha?
Siddharth
Não podemos enviar nenhum elemento novo para uma pilha, mas, de acordo com 5, somos capazes de enviar o elemento superior de uma pilha para outra. Portanto, copiar a pilha na ordem inversa requer no máximo tempo linear. Então suponho que não era isso que você estava pedindo?
cero 28/02
Você não pode colocar nada em cima de outros itens, como explicado na pergunta.
Kaveh 28/02