Ordina array di 5 numeri interi con un massimo di 7 confronti


19

Come posso ordinare un elenco di 5 numeri interi in modo tale che nel peggiore dei casi ci vogliono 7 confronti? Non mi importa di quante altre operazioni vengono eseguite. Non so nulla di particolare sugli interi.

Ho provato alcuni approcci di divisione e conquista diversi che mi portano a 8 confronti, ad esempio seguendo un approccio di fusione, o combinando fusione con l'uso della ricerca binaria per trovare la posizione di inserimento, ma ogni volta che finisco con 8 confronta il caso peggiore .

In questo momento sto solo cercando un suggerimento, non una soluzione.


Hai provato a scrivere l'albero "confronta con"? Ha foglie, ciascuna corrispondente a una permutazione degli interi. Se non sai cosa intendo per albero "confronta-con", conosci la prova che hai bisogno di n log n confronti? Ps, cosa ti fa pensare che sia possibile? 5!=120nlogn
Pål GD,

1
Bene, nel complemento di 8 bit due, if(x > y)è lo stesso if((x - y) & 0x80)che non è quasi un confronto. Immagino che dovremmo dimenticare che gli oggetti sono numeri interi e presumere che dobbiamo usare alcune compare(x, y)funzioni magiche per confrontare quegli oggetti ...
Karolis Juodelė

2
'Controlla la sezione 5.3 sull'ordinamento ottimale nel Volume 3 di The Art Of Computer Programming , che copre esattamente questa domanda' conta come un suggerimento o una soluzione? :-)
Steven Stadnicki

3
Il limite è davvero che e 5 ! = 120 < 2 7 = 128 . Quindi è possibile (in linea di principio). 2cn!5!=120<27=128
vonbrand,

Risposte:


23

C'è solo un modo per iniziare questo processo (e per quasi tutte le tue decisioni su cosa confrontare nei passaggi successivi, ce n'è solo uno corretto). Ecco come capirlo. Innanzitutto, nota che ci sono possibili risposte che puoi ottenere per i tuoi confronti e 5 ! = 120 diverse permutazioni che devi distinguere tra.27=1285!=120

Il primo confronto è semplice: devi confrontare due chiavi e poiché non ne sai nulla, tutte le scelte sono ugualmente buone. Quindi diciamo che si confronta e b , e scoprire che un b . Ora hai 2 6 = 64 possibili risposte rimanenti e 60 possibili permutazioni rimanenti (poiché ne abbiamo eliminato la metà).abab26=6460

Successivamente, possiamo confrontare e d oppure possiamo confrontare c con una delle chiavi che abbiamo usato nel primo confronto. Se confrontiamo c e d e apprendiamo che c d , allora abbiamo 32 risposte rimanenti e 30 possibili permutazioni. D'altra parte, se si confronta c con una , e scoprire che un c , abbiamo 40 possibili permutazioni rimanenti, poiché abbiamo eliminato 1 / 3 delle possibili permutazioni (quelli con c cdccdcd3230caac401/3 ). Abbiamo solo 32 possibili risposte rimanenti, quindi siamo sfortunati.cab32

Quindi ora sappiamo che dobbiamo confrontare la prima e la seconda chiave e la terza e la quarta chiave. Possiamo assumere che abbiamo e c d . Se mettiamo a confronto e ad una di queste quattro chiavi, per lo stesso argomento che abbiamo usato nel passaggio precedente, si potrebbe eliminare solo 1 / 3 delle permutazioni rimanenti, e siamo fuori di fortuna. Quindi dobbiamo confrontare due dei tasti a , b , c , d . Tenendo conto della simmetria, abbiamo due scelte, confrontare a e c oppure confrontare a e dabcde1/3a,b,c,dacad. Un argomento di conteggio simile mostra che dobbiamo confrontare e c . Possiamo supporre senza perdita di generalità che a c , e ora abbiamo a b e a c d .acacabacd

Dato che hai chiesto un suggerimento, non analizzerò il resto dell'argomento. Ti restano quattro confronti. Usali saggiamente.


Come hai fatto che il confronto a c si ottiene solo fino a 40 permutazioni? ac
Robert S. Barnes,

1
@ Robert: Supponiamo di avere e un c . Quindi ci sono due permutazioni di a , b , c coerenti con questi vincoli, a < b < c e a < c < b . Per ognuna di queste due permutazioni, ci sono quattro posizioni in cui è possibile aggiungere d e cinque posizioni in cui è possibile aggiungere e . abaca,b,ca<b<ca<c<bde
Peter Shor,

8

Puoi trovarlo in The Art of Computer Programming vol III, di D.Knuth, ma la strategia è la seguente (suppongo che tu abbia array ): se vuoi un suggerimento leggi solo le prime due righe della mia risposta{a,b,c,d,e}

  • Coppie di numeri del primo gruppo: .(a,b),(c,d)
  • Confronta le coppie per ordinarle, ad esempio: .a<b,c<d
  • Confronta più piccoli elementi di coppie, otteniamo dei risultati ad esempio .a<c
  • Confronta l'ultimo elemento , con l'elemento più grande nell'ultimo confronto ( c ) ec
    • Se , è facile finire con 3 confronti rimanenti. Finito.e<c
    • Se allora dovresti ordinare { b , c , d , e } con conoscenza c < e , c < d . e>c{b,c,d,e}c<e,c<d
      • , se d < e allora Compare(d,e)d<e
        • Compare(b,d)b>d
          • Compare(b,e)
        • b<d
          • Compare(b,c)
      • d>e
        • Compare(b,e)b>e
          • Compare(b,d)
        • b<e
          • Compare(b,c)

ec


Sei sicuro che sia corretto? Supponiamo di ottenere i seguenti risultati: a <b, c <d, a <c e quindi c <e, b <e, c <b e d <e. Gli ordini a <c <b <d <e e a <c <d <b <e sono entrambi coerenti con essi. Il motivo è che b e d non vengono mai confrontati, implicitamente o esplicitamente. Forse mi sbaglio da qualche parte, in tal caso, per favore, correggimi.
George
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.