Tri à l'aide de piles en lecture seule

14

Considérez le paramètre suivant:

  • on nous donne une pile qui contient n éléments.sn
  • nous pouvons utiliser un nombre constant de piles supplémentaires.O(1)
  • nous pouvons appliquer les opérations suivantes sur ces piles:
    1. vérifier si une pile est vide,
    2. comparer les éléments supérieurs de deux piles,
    3. supprimer l'élément supérieur d'une pile,
    4. imprimer l'élément supérieur dans une pile,
    5. copier l'élément supérieur d'une pile dans une autre pile,
    6. copier le contenu d'une pile dans une autre pile.

Notez que ce sont les seules opérations autorisées. Nous ne pouvons pas échanger des éléments et nous ne sommes pas autorisés à pousser un élément sur l'une des piles à l'exception de la copie de l'élément supérieur dans une pile (après quoi le contenu précédent de la pile cible est rejeté et il ne contiendra que l'élément copié) .

Voici un algorithme pour trier les piles avec comparaisons O ( n 2 ) :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

Pouvons-nous faire mieux?

Existe-t-il un programme qui imprime la liste triée des éléments dans les piles en utilisant uniquement comparaisons log n ) ?O(nJournaln)

Siddharth
la source
2
On dirait que les registres se comportent comme des piles? Il semble que vous parliez d'opérations push et pop. Ce sont vos questions? Comment classeriez-vous une pile en utilisant plusieurs piles et opérations de pile?
AturSams
2
Avec registres, vous pouvez: simplement mettre chaque nombre dans un registre ( O ( n ) ) puis appliquer un algorithme de tri habituel ( O ( n lg n ) ). nO(n)O(nlgn)
Kaveh
1
Voulez-vous utiliser des registres ? Sinon, le problème banalise, comme l'a commenté Kaveh. O(1)
Yuval Filmus
1
Je vous en prie. Je pensais qu'on nous donnait un certain nombre de piles, pas une seule, je vais le réparer.
Kaveh
2
@akappa, êtes-vous sûr que cela peut être utilisé dans cette vision? Nous ne pouvons pas conserver de perte arbitraire de taille supérieure à 1. Vous n'avez pas besoin de stocker les blocs triés?
Kaveh

Réponses:

1

Je pense que je peux maintenant démontrer une borne inférieure non triviale. L'idée est de mettre en œuvre un tel programme avec une famille de programmes de branchement de comparaison. L'hypothèse "en lecture seule" signifie que notre famille de programmes de branchement utilise peu d' espace , c'est-à-dire . Ensuite, nous appliquons la borne inférieure S T = Ω ( n 2 ) prouvée par Borodin et al. dans "A Time-Space Tradeoff for Sorting on non-inconscious Machines". Cela nous donne un n 2 / log nO(Journaln)ST=Ω(n2)n2/Journaln limite inférieure pour le moment.

Plus en détail: on peut se passer de l'opération 5 ci-dessus. En gros, si nous pouvons déjà comparer les têtes de deux listes et imprimer la tête d'une liste, il n'est pas nécessaire pour nous d'isoler la tête d'une liste sur un registre particulier. En supposant cela, nous voyons que chaque registre de la machine ne stocke que la sous-chaîne finale de l'entrée.

Supposons que notre programme de registres ait lignes de code et k registres, X 1 , , X k .kX1,,Xk

Fixez . Nous construisons le programme de branchement de comparaison pour les chaînes de longueur n comme suit. Créez un nœud pour chaque tuple ( i , d 1 ,nn 1 i et 0 d 1 , , d kn . L'idée est que les calculs dans la machine de registre correspondent aux chemins dans le programme de branchement, et nous sommes au nœud ( i , d 1 , , d(i,d1,,dk)1i0d1,,dkn si nous sommes à la ligne i dans la machine de registre et que la longueur de la chaîne stockée dans X i est d i . Maintenant, nous devons définir les bords dirigés du programme de branchement(i,d1,,dk)jeXjeje

Si la ligne est de la formei

si alors goto i 1 d' autre goto i 2Xu<Xvi1i2

alors pour tout , le nœud ( i , d 1 , , d k ) est étiqueté en comparant le d ud1,,dk(i,d1,,dk)du élément -th et -th d'entrée, et en ayant le bord «vrai» aller à ( i 1 , d 1 , , d k ) , et le bord «faux» à ( i 2 , d 1 , , d kdv(i1,d1,,dk) .(i2,d1,,dk)

Si la ligne est de la formei

, passez à la ligne i X1tail(X2)i

alors il y a une flèche de n'importe quel nœud à ( i , d 2 - 1 , , d k )(i,d1,,dk)(i,d21,,dk) .

Si la ligne est de la formei

, passez à la ligne i print(head(Xu))i

alors il y a une flèche de n'importe quel nœud (i,d1,,dk)(i,d1,,dk)du

nkO(logn)

Siddharth
la source
0

Êtes-vous capable de compter les éléments? Ensuite, je pense qu'il y a une implémentation de Mergesort assez facile. Si vous pouviez mettre des symboles supplémentaires sur la pile, vous pourriez le résoudre avec 3 piles comme ceci:

Si nous n'avons qu'un seul élément, la liste est déjà triée. Supposons maintenant que nous avons déjà trié la moitié supérieure de la pile. Nous pouvons copier la moitié supérieure (dans l'ordre inverse) dans la deuxième pile et placer un symbole de séparation dessus. Maintenant, nous avons à nouveau 3 piles (car nous pouvons ignorer les symboles déjà triés sous le symbole de séparation) et pouvons trier la moitié inférieure. Enfin, nous pouvons copier la moitié inférieure triée dans une troisième pile dans l'ordre inverse et fusionner les deux moitiés dans la pile d'origine.

O(nlogn)

nlogn


Comme vous ne pouvez pas mettre de nouveaux éléments sur la pile, vous pouvez rencontrer des problèmes aux points de séparation. Pour résoudre ce problème, vous pouvez effectuer les opérations suivantes avec des piles supplémentaires:

n2logn

Enfin, répétez la procédure avec les éléments supplémentaires au plus lognccnlogn+cn2logn2+cn4logn4+ ...=O(nlogn)O(nlogn)

cero
la source
Je ne suis pas sûr de comprendre. Comment pouvons-nous, par exemple, copier la moitié supérieure de la pile dans l'ordre inverse sur une autre pile alors que nous ne pouvons jamais pousser aucun élément sur une pile?
Siddharth
Nous ne pouvons pas pousser un nouvel élément vers une pile, mais selon 5, nous pouvons pousser l'élément supérieur d'une pile vers une autre. La copie de la pile dans l'ordre inverse nécessite donc au maximum un temps linéaire. Donc je suppose que ce n'était pas ce que vous demandiez?
cero
Vous ne pouvez rien pousser par-dessus d'autres éléments comme expliqué dans la question.
Kaveh