2010-12-07 15 views
9

Ich dachte nur, wenn ich std::inplace_merge es wahrscheinlich so etwas wie dies aussehen würde implementieren waren:Ist es möglich, eine Inplace Merge ohne temporären Speicher durchzuführen?

template <class Bi, class Cmp> 
void inplace_merge(Bi first, Bi middle, Bi last, Cmp cmp) { 
    if(first != last) { 
     typedef typename iterator_traits<Bi>::value_type T; 
     typedef typename iterator_traits<Bi>::difference_type Dist; 

     const Dist count = distance(first, last); 
     if(count != 1) { 
      // can I avoid this allocation? 
      T *const temp = new T[count];  
      merge(first, middle, middle, last, temp, cmp);  
      copy(temp, temp + count, first); 
      delete [] temp; 
     } 
    } 
} 

Ich weiß, dass ich nur die vorhandene Implementierung verwenden könnte, aber das ist irgendwie nebensächlich. Ich war nur neugierig, ob es einen besseren Algorithmus als das, was ich weiß, gab.

Der Grund dafür in den Sinn kam, dass die meisten der C++ Standardbibliothek (alle von der STL, wenn ich mich recht erinnere), der Benutzer angeben können, wie und wo Zuweisungen ausführen, aber wenn std::inplace_merge erfordert eine Zuweisung von Design es scheint, dass es keine Möglichkeit gibt, dies zu kontrollieren, wenn es ein Problem wäre.

denke ich, ein Hinweis auf die Antwort aus dem Standard kommt selbst in Bezug auf die Komplexität der std::inplace_merge:

Komplexität: Wenn genügend zusätzliche Speicher verfügbar ist, (letzte - erste) - 1 Vergleiche. Wenn kein zusätzlicher Speicher verfügbar ist, kann ein Algorithmus mit Komplexität N log N (wobei N gleich ist, um zuletzt zu dauern) verwendet werden.

Für mich bedeutet dies, dass die bekannten effizienten Versionen des Algorithmus zusätzlichen Speicherplatz benötigen. Lies ich das richtig? Wenn ja, wird erwähnt, woher der Speicher kommen soll?

+1

In-Place, * per Definition *, erfordert keine zusätzlichen Speicherzuweisungen (es erfordert nur O (1) temporären Speicher auf dem Stapel). Ihre Implementierung ist nicht vorhanden. –

+1

@Adam: Inkorrekt, bedeutet dies, dass die Ergebnisse im selben Speicher wie die Quelle sind (im Gegensatz zu nur 'merge', die die Ergebnisse in einen vom Aufrufer bereitgestellten Puffer legt). Beispielsweise verwendet STLPort temporären Speicher in der Form von: '_Temporary_buffer <_BidirektionalIter, _Tp >__buf (__ zuerst, __last);' wenn Sie ihre Implementierung betrachten. –

+7

Nach weiteren Untersuchungen scheint es, dass es keine einzige Definition von "in-place" gibt (siehe http://en.wikipedia.org/wiki/In-place_algorithm). Die traditionelle Definition, die von Algorithmus-Theoretikern verwendet wird, ist eine, die O (1) zusätzlichen Speicher verwendet, während diejenige, die vom C++ - Standard verwendet wird, offensichtlich dieselbe verwendet, die den gleichen Speicher für Eingabe und Ausgabe verwendet. –

Antwort

10

Es gibt mehrere bekannte Algorithmen zum Mischen in-Place, obwohl einige von ihnen ziemlich komplex sind. Die allgemeine Art und Weise, in der sie arbeiten, besteht darin, eine nicht erfolgte Verschmelzung durchzuführen, wobei einige der Array-Elemente selbst als externer Speicherplatz verwendet werden. Ich weiß, dass Alex Stepanov und Paul McJones '"Elements of Programming" einen Algorithmus beschreiben.

Ich habe vor kurzem eine Arbeit über In-Place-Merging namens "Practical In-Place Merging" gelesen, die einen ziemlich einfachen Algorithmus für diese Art der Zusammenführung beschreibt. Ich codierte an implementation of this algorithm in einer Weise, die nahe der Schnittstelle von std::inplace_merge ist, obwohl es ein paar Unterschiede gibt. Vielleicht gibt es da etwas, das Sie nützlich finden könnten?

+0

Wahrscheinlich einer der am besten dokumentierten Codeabschnitte, die ich gesehen habe. Da sind ein paar C-Ismen drin (Kommentare, Casts) aber es ist sehr gut präsentiert. –

+0

+1 Diese Antwort wird von pure Ehrfurcht und flat-out-Gewinn gemacht.Ich bin mit dem erwähnten Papier vertraut, aber mir die Zeit zu nehmen, es zu implementieren, auch wenn es nicht für diese Antwort ist, es als Live-Action-Referenz zu präsentieren, ist einfach hervorragend. Vielen Dank. – WhozCraig

Verwandte Themen