it-swarm.com.de

Sortierzeit und Raumkomplexität zusammenführen

Nehmen wir diese Implementierung von Merge Sort als Beispiel

void mergesort(Item a[], int l, int r) {
if (r <= l) return;
int m = (r+l)/2;
mergesort(a, l, m);  ------------ (1)
mergesort(a, m+1, r); ------------(2)
merge(a, l, m, r);

a) Die zeitliche Komplexität dieser Zusammenführungssortierung beträgt O (nlg (n)). Wird das Parallelisieren von (1) und (2) einen praktischen Gewinn bringen? Theoretisch scheint es, als würden Sie nach dem Parallelisieren auch in O (nlg (n)) enden. Aber können wir praktisch Gewinne erzielen?

b) Die Raumkomplexität dieser Zusammenführungssortierung ist hier O (n). Wenn ich mich jedoch für die direkte Sortierreihenfolge mit verknüpften Listen entschieden habe (nicht sicher, ob Arrays vernünftig durchgeführt werden können), wird die Platzkomplexität zu O (lg (n)), da die Frame-Größe des Rekursionsstacks berücksichtigt werden muss ? Können wir O(lg(n)) als konstant behandeln, da es nicht mehr als 64 sein kann? Ich habe das an einigen Stellen missverstanden. Was genau ist die Bedeutung von 64?

c) http://www.cprogramming.com/tutorial/computersciencetheory/sortcomp.html sagt, dass die Sortierreihenfolge einen konstanten Speicherplatz unter Verwendung verknüpfter Listen erfordert. Wie ? Haben sie O(lg(n) konstant behandelt?

d) [Zur besseren Übersichtlichkeit hinzugefügt] Für die Berechnung der Raumkomplexität kann man davon ausgehen, dass sich das Eingabe-Array oder die Liste bereits im Speicher befindet? Wenn ich Komplexitätsberechnungen durchführe, berechne ich immer den zusätzlichen Platz, den ich zusätzlich zu dem bereits benötigten Platz benötigen werde. Andernfalls ist die Platzkomplexität immer O(n) oder schlechter. 

20
Frank Q.

a) Ja - in einer perfekten Welt müssten Sie loggene Zusammenführungen der Größe n, n/2, n/4 ... (oder besser 1, 2, 3 ... n/4, n/2) durchführen , n - sie können nicht parallelisiert werden), was O (n) ergibt. Es ist immer noch O (n log n). In einer nicht so perfekten Welt haben Sie nicht unendlich viele Prozessoren, und Kontextwechsel und Synchronisierung kompensieren mögliche Gewinne.

b) Die Raumkomplexität ist immer Ω (n), da die Elemente irgendwo gespeichert werden müssen. Eine zusätzliche Platzkomplexität kann O(n) in einer Implementierung mit Arrays und O(1) in Implementierungen verknüpfter Listen sein. In der Praxis benötigen Implementierungen, die Listen verwenden, zusätzlichen Platz für Listenzeiger. Wenn Sie also die Liste nicht bereits im Speicher haben, sollte dies keine Rolle spielen.

edit wenn Sie Stack-Frames zählen, ist dies O (n) + O (log n), also bei Arrays immer noch O(n). Bei Listen ist dies O (log n) zusätzlicher Speicher.

c) Listen benötigen nur einige Zeiger, die während des Zusammenführungsvorgangs geändert wurden. Das erfordert ständig zusätzlichen Speicher.

d) Deshalb erwähnen die Leute bei der Merge-Sort-Komplexitätsanalyse „zusätzlichen Platzbedarf“ oder ähnliches. Es ist offensichtlich, dass Sie die Elemente irgendwo aufbewahren müssen, aber es ist immer besser "zusätzlichen Speicher" zu nennen, um Puristen fernzuhalten.

16
soulcheck

MergeSort-Zeit Die Komplexität ist O(nlgn), was ein grundlegendes Wissen ist. Zusammenführungs-Sortierraum-Komplexität wird immer O(n) einschließlich von Arrays sein. Wenn Sie den Space-Tree herausziehen, scheint es, als ob die Space-Komplexität O (nlgn) ist. Da es sich bei dem Code jedoch um einen Depth First-Code handelt, werden Sie immer nur entlang eines Zweigs der Baumstruktur erweitert. Daher wird der gesamte erforderliche Speicherplatzbedarf immer durch O(3n) = O (n) begrenzt. 

Wenn Sie beispielsweise den Space-Tree zeichnen, scheint es, als wäre es O (nlgn).

                             16                                 | 16
                            /  \                              
                           /    \
                          /      \
                         /        \
                        8          8                            | 16
                       / \        / \
                      /   \      /   \
                     4     4    4     4                         | 16
                    / \   / \  / \   / \
                   2   2 2   2.....................             | 16
                  / \  /\ ........................
                 1  1  1 1 1 1 1 1 1 1 1 1 1 1 1 1              | 16

die Höhe des Baumes ist O(logn) => Die Raumkomplexität ist O (nlogn + n) = O (nlogn). Dies ist jedoch im tatsächlichen Code nicht der Fall, da er nicht parallel ausgeführt wird. In dem Fall, in dem N = 16 ist, führt dies beispielsweise den Code für Mergesort aus. N = 16. 

                           16
                          /
                         8
                        /
                       4
                     /
                    2
                   / \
                  1   1

beachten Sie, dass die Anzahl der verwendeten Speicherplätze 32 = 2n = 2 * 16 <3n ist

Dann verschmilzt es nach oben 

                           16
                          /
                         8
                        /
                       4
                     /  \
                    2    2
                        / \                
                       1   1

das ist 34 <3n . Dann verschmilzt es nach oben

                           16
                          /
                         8
                        / \
                       4   4
                          /
                         2
                        / \ 
                       1   1

36 <16 * 3 = 48 

dann verschmilzt es nach oben 

                           16
                          / \
                         8  8
                           / \
                          4   4
                             / \
                            2   2
                                /\
                               1  1

16 + 16 + 14 = 46 <3 * n = 48 

in einem größeren Fall ist n = 64 

                     64
                    /  \
                   32  32
                       / \
                      16  16
                          / \
                         8  8
                           / \
                          4   4
                             / \
                            2   2
                                /\
                               1  1

das ist 64 * 3 <= 3 * n = 3 * 64 

Sie können dies durch Induktion für den allgemeinen Fall beweisen. 

Daher ist die Komplexität des Speicherplatzes immer durch O(3n) = O(n) begrenzt, auch wenn Sie mit Arrays implementieren, solange Sie den verwendeten Space nach dem Zusammenführen bereinigen und keinen Code parallel, sondern sequentiell ausführen. 

Ein Beispiel für meine Implementierung ist unten angegeben: 

templace<class X> 
void mergesort(X a[], int n) // X is a type using templates
{
    if (n==1)
    {
        return;
    }
    int q, p;
    q = n/2;
    p = n/2;
    //if(n % 2 == 1) p++; // increment by 1
    if(n & 0x1) p++; // increment by 1
        // note: doing and operator is much faster in hardware than calculating the mod (%)
    X b[q];

    int i = 0;
    for (i = 0; i < q; i++)
    {
        b[i] = a[i];
    }
    mergesort(b, i);
    // do mergesort here to save space
    // http://stackoverflow.com/questions/10342890/merge-sort-time-and-space-complexity/28641693#28641693
    // After returning from previous mergesort only do you create the next array.
    X c[p];
    int k = 0;
    for (int j = q; j < n; j++)
    {
        c[k] = a[j];
        k++;
    }
    mergesort(c, k);
    int r, s, t;
    t = 0; r = 0; s = 0;
    while( (r!= q) && (s != p))
    {
        if (b[r] <= c[s])
        {
            a[t] = b[r];
            r++;
        }
        else
        {
            a[t] = c[s];
            s++;
        }
        t++;
    }
    if (r==q)
    {
        while(s!=p)
        {
            a[t] = c[s];
            s++;
            t++;
        }
    }
    else
    {
        while(r != q)
        {
            a[t] = b[r];
            r++;
            t++;
        }
    }
    return;
}

Hoffe das hilft! =)

Bald Chee Loong, 

Universität von Toronto 

49
Chee Loong Soon

a) Ja, die parallelisierende Zusammenführungssortierung kann natürlich sehr vorteilhaft sein. Es bleibt nlogn, aber Ihre Konstante sollte deutlich niedriger sein.

b) Die Raumkomplexität mit einer verknüpften Liste sollte O (n) oder genauer O(n) + O (logn) sein. Beachten Sie, dass dies ein + ist, kein *. Kümmern Sie sich bei asymptotischen Analysen nicht viel um Konstanten.

c) In der asymptotischen Analyse ist nur der dominante Term in der Gleichung von Bedeutung, daher macht die Tatsache, dass wir ein + und nicht ein * haben, es zu O (n). Wenn wir die Unterlisten überall duplizieren würden, glaube ich, wäre dies O(nlogn) -, aber eine intelligente Sortierung mit verknüpfter Liste kann Bereiche der Listen gemeinsam nutzen.

1
user1277476

Worst-Case-Performance der Zusammenführungssortierung: O (n log n) , Best-Case-Performance der Zusammenführungssortierung: O (n log n) typischey, O(n) natürliche Variante , Durchschnittliche Leistung der Zusammenführungssortierung: O (n log n) , Worst-Case-Komplexität der Zusammenführungssortierung: О (n) total, O(n) Hilfs

1
Sourabh

für den besten und den schlechtesten Fall ist die Komplexität O(nlog(n)). obwohl in jedem Schritt eine zusätzliche N-Größe des Arrays erforderlich ist, ist die Raumkomplexität O (n + n) O(2n), da wir den konstanten Wert für die Berechnung der Komplexität entfernen, so dass sie O (n) ist

0
fuad ashraful

Space Complexity: Space-Komplexität: Es ist nicht bekannt, ob auf jeder Ebene ein Unterfeld/eine Unterliste erstellt wird (logn-Ebenen * n auf jeder Ebene erforderlicher Speicherplatz => logn * n) und n (n + logn = n) für Array . Zeitkomplexität: nlogn für den schlechtesten und durchschnittlichen Fall

0
nikhil.singhal

die Komplexität des Zusammenführungssortierraums ist O(nlogn), dies ist ziemlich offensichtlich, wenn man bedenkt, dass es maximal O(logn) Rekursionen geben kann, und für jede Rekursion gibt es zusätzlichen Raum für O(n) zum Speichern des zusammengeführten Arrays, das neu zugewiesen werden muss. Für diejenigen, die O(n) sagen, vergessen Sie bitte nicht, dass es O(n) ist, um die Stapelrahmentiefe zu erreichen.