Come implementare due stack in un array?


15

Voglio iniziare dicendo che questa NON è una domanda da fare a casa. Sto leggendo Introduzione agli algoritmi - il famoso testo CLRS per diventare un programmatore migliore. Sto cercando di risolvere da solo i problemi e gli esercizi dati nel libro.

Sto cercando di risolvere Excercise 10.1-2 dal capitolo 10 Strutture di dati elementari della seconda edizione di CLRS. Ecco cosa afferma:

Spiegare come implementare due stack in un array A [1..n] in modo tale che nessuno degli stack trabocchi a meno che il numero totale di elementi in entrambi gli stack sia n . Le operazioni PUSH e POP dovrebbero essere eseguite in O (1) .

La soluzione che ho escogitato finora è:

Consenti all'array A [1..n] di implementare due stack: S1 [1..i] e S2 [i..n] .

Per le operazioni PUSH-S1 e PUSH-S2 , se lo stack è "pieno", iniziare a spingere gli elementi nell'altro stack (ad es. Se lo stack S1 è pieno quando un nuovo elemento sta cercando di essere inserito, quindi spingere quell'elemento in stack S2 e viceversa).

Il problema con questo approccio è che non sarò in grado di POP-S1 o POP-S2 in modo affidabile poiché non c'è modo di "ricordare" quale elemento appartiene a quale stack. Se gli elementi dello stack sono coppie (chiave, valore) , la chiave è il numero dello stack, quindi per far apparire un elemento dovrei cercare, nel peggiore dei casi, i o (ni) volte - che sarà O (n ) (sentiti libero di correggermi se sbaglio qui), che non sarebbe O (1) .

Sto sbattendo la testa sulla domanda da un po 'di tempo ormai. Sono sulla buona strada? Qualcuno può dare i miei possibili suggerimenti per risolvere questo problema?

In generale, come dovrei "pensare" a questi problemi? O solo le persone veramente intelligenti possono risolvere questo tipo di problemi? Affrontare / risolvere problemi come questi (ovvero acquisire esperienza) mi aiuterà a migliorare in questo?

Attendo l'illuminazione.


3
"Affrontare / risolvere problemi come questi (vale a dire acquisire esperienza) mi aiuterà a migliorare in questo?" Nella mia esperienza, questo è sicuramente il caso. Se non altro, avrai pensato in molti modi al problema, e da solo svilupperai maggiori informazioni. Come mi è stato recentemente detto: il modo migliore per avere buone idee è avere molte idee.
G. Bach,

Risposte:


7

Un altro suggerimento in aggiunta a quello che ha detto Yuval: aiuta a posizionare le pile in un modo specifico negli array e a fissare di conseguenza la loro direzione di crescita. Non devono crescere nella stessa direzione.


5

Ecco alcuni suggerimenti:

  1. Una delle pile dovrebbe crescere "in alto" e l'altra "in basso".
  2. Non c'è modo di 'ricordare' quale elemento appartiene a quale pila - ti è permesso usare variabili aggiuntive per aiutarti con cose del genere. (Questo ha più senso con la soluzione proposta dal primo suggerimento.)

1

Il primo stack inizia da 1 e cresce verso n, mentre il secondo inizia da n e cresce verso 1. L'overflow dello stack si verifica quando viene premuto un elemento quando i due puntatori dello stack sono adiacenti.


1

Questo metodo utilizza in modo efficiente lo spazio disponibile. Non provoca un overflow se c'è spazio disponibile in arr []. L'idea è di iniziare due stack da due angoli estremi di arr []. stack1 inizia dall'elemento più a sinistra, il primo elemento nello stack1 viene spinto nell'indice 0. Lo stack2 inizia dall'angolo più a destra, il primo elemento nello stack2 viene spinto nell'indice (n-1). Entrambe le pile crescono (o si restringono) in direzione opposta. Per verificare l'overflow, tutto ciò di cui abbiamo bisogno è lo spazio tra gli elementi superiori di entrambe le pile.


-1

Ho pensato a un'altra soluzione. Se dividiamo l'array a metà (o il più vicino possibile se l'array ha una lunghezza dispari) e facciamo andare il primo elemento nel primo stack e il secondo elemento nel secondo stack. Mentre saltiamo fuori potremmo ritornare su questi passaggi. Tuttavia, implementando in questo modo, violerebbe qualsiasi principio dello stack?


Benvenuti in Informatica ! Sfortunatamente, la tua proposta non funziona. In una matrice di lunghezzaN, dovresti essere in grado di memorizzare due pile che non traboccheranno a meno che la loro dimensione totale non superi N (quindi dovrebbe essere in grado di far fronte a una pila vuota e una pila di lunghezzaN). La soluzione trabocca se una delle pile superaN/2.
David Richerby,

-2

Alcuni suggerimenti

Crea un array

Gli elementi dell'array con indice dispari sono per stack1

Gli elementi dell'array con indice pari sono per stack2

Ora puoi far crescere entrambe le pile da sinistra a destra

Mantieni solo le variabili che mantengono la posizione più alta di entrambe le pile. Non dovrai cercare nell'array.

e se stack1 diventa pieno mentre stack2 è vuoto, è possibile tenere traccia degli elementi stack1 aggiuntivi nello stack2 mantenendo alcune variabili


Questo è molto contorto. Le risposte esistenti offrono già modi molto più semplici per risolvere il problema
David Richerby,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.