Sortierung in c zusammenführen

Sortierung in c zusammenführen
Viele Computersprachen haben heute eine allgemeine Sort () -Funktion in der Bibliothek. Diese Funktion wird für kommerzielle Anwendungen verwendet. Viele Programmierer verwenden die von der Sprachbibliothek bereitgestellte Sortierfunktion, wenn sie eine Sortierfunktion benötigen.

Das normal geschriebene Mergesort -Programm ist vergleichbar (in Bezug auf die Geschwindigkeit) mit der von C ++ in seiner Algorithmusbibliothek bereitgestellten Sort () -Funktion. Merge-Sort ist auch ein allgemeines kommerzielles Programm.

In diesem Artikel wird erläutert, wie das Mergesort -Programm in der C -Sprache geschrieben wird.

Divide-and-Conquer-Algorithmus in seinem breiten Sinne

In seinem breiten Sinne ist die Auswahl der Elemente in zwei Hälften unterteilt: die linke Hälfte und die rechte Hälfte. Wenn die Gesamtzahl der sortierten Elemente seltsam ist, wird die linke Hälfte größer als die rechte Hälfte von 1 Einheit. Ansonsten sind beide Hälften gleich lang. Die beiden Hälften werden dann verschmolzen, während sie auf ein sortiertes Array sortiert werden. Die Verschmelzung/Sortierung erobert. Betrachten Sie die folgenden Zeichen, die sortiert werden sollen:

Q w e r t y u i o p

Wenn Sie diesen Satz alphabetischer Zeichen in zwei Hälften teilen, gibt es:

Q w e r t y u i o p

Ein Sub -Array wird als Lauf bezeichnet. Das linke Sub -Array "Q w e r t" ist also ein Lauf und das rechte Sub -Array, "y u i o p" ist ebenfalls ein Lauf. Ein Lauf kann auch nur ein Element haben.

Das Zusammenführen/Sortieren (erobern) beide Hälften in ein Satz gibt::

E i o p q r t u w y

Der Code, der durch 2 dividiert wird, lautet:

int iMiddle = (iBegin + iend) / 2;

Dies ist eine ganzzahlige Abteilung. Der gesamte Teil des Ergebnisses wird also genommen. Wenn die Gesamtzahl der Elemente im Set ungerade ist, wäre die linke Hälfte größer als die rechte Hälfte, eine Einheit für Null -Basis -Indexierung.

Für die obige Anweisung und die Set, 'q', 'w', 'e', ​​'r', 't', 'y', 'u', 'I', 'O', P ', iBegin = 0, iend = 10 (was der letzte Index von 9, plus 1), Imiddle = 5;

Der Code zum Zusammenführen/Sortieren (Eroberung) lautet:

int i = iBegin;
int j = Imiddle;
für (int k = iBegin; k if (i = iend || p [i] <= P[j]))
Q [k] = P [i];
i = i + 1;
anders
Q [k] = P [j];
J = J + 1;

P ist das angegebene Array. Q hätte das sortierte Array in diesem Fall.

Wenn dieser Code auf den Satz 'q', 'w', 'e', ​​'r', 't', 'y', 'u', 'i', 'O', P ' angewendet wird Es wird die geteilten Hälften verschmelzen, aber keine Sortierung (weil jedes Element im linken Lauf geringer ist als 'y'). Dieser Code wird unten überarbeitet, um seine Wirksamkeit bei der Sortierung eines aufeinanderfolgenden Paares von Läufen zu zeigen.

Praktischer Divide-and-Conquer-Algorithmus

Das gesamte Mergesort-Programm kann oben nach unten oder unten nach oben geschrieben werden. In diesem Artikel wird das Programm oben nach unten geschrieben.

Ein Mergesort funktioniert auf folgende Weise konzeptionell:

1) Teilen Sie den ungeortierten Set in N -Teilmengen (Läufe), wobei jedes ein Element hat. Beachten Sie, dass ein Satz mit nur einem Element als sortiert betrachtet wird.

2) Fusionen Sie die Untergruppen wiederholt zusammen, um neue sortierte Teilmengen zu erhalten, bis nur eine Teilmenge übrig ist. Dies ist das sortierte Set.

Mit diesen beiden Punkten ist ein bestimmtes Ichs in zwei Läufen unterteilt. Jeder dieser beiden Läufe wird im Speicher zum Zusammenführen/Sortieren im Speicher aufgezeichnet, aber noch nicht zusammengeführt oder sortiert. Jeder Lauf wieder auf beiden Seiten ist in zwei unterteilt. Die aufeinanderfolgenden Läufpaare werden zum Zusammenführen/Sortieren zusammengestellt, aber noch nicht zusammengeführt oder noch nicht sortiert. Diese Aufteilung in zwei und die Aufzeichnung zum Zusammenführen/Sortieren aufeinanderfolgender Paare wird wiederholt, bis nur ein Element pro Lauf vorhanden ist.

Die Aufzeichnung in den Speicher zum Zusammenführen/Sortieren von aufeinanderfolgenden Läufen erfolgt durch den oben genannten Sortiercode rekursiv nach der Abteilung. Der Sortiercode befindet sich in einer getrennten Funktion. Die Abteilungserklärung und die Aufruf der Sortierfunktion (die auch zusammengeführt) befindet.

Wenn die Abteilung den Stand der einzelnen Elementläufe erreicht hat, werden die im Speicher aufgezeichneten Zusammenführungs-/Sortierfunktionen in umgekehrter Reihenfolge aufgerufen, in der sie aufgezeichnet wurden. Es handelt sich um eine Zusammenführungs-/Sortierfunktion, die viele Male im Speicher mit unterschiedlichen Argumenten aufgezeichnet wurde. Konsekutive Paare von einzelnen Elementen werden zuerst sortiert und gleichzeitig zusammengeführt. Die Sortierung und Verschmelzung von aufeinanderfolgenden Läufen wird fortgesetzt, bis das gesamte Set sortiert ist. Die Sortierung geht also nicht wirklich auf der Anordnung von Elementen ab, wie ursprünglich angegeben wurde.

In C besteht ein Bedarf an einem zweiten Array, dessen Länge so lang ist wie das angegebene Array. Zunächst müssen alle Elemente für dieses zweite Array erstellt werden, der Standardwert des Datentyps. Die Elemente des angegebenen Arrays werden in dieses zweite Array sortiert. Dann kopierte sie in das angegebene Array zurück und überschrieben die unortierten Elemente.

Für Zeichen kann dieses zweite Array wie folgt erstellt und initialisiert werden:

char p [] = 'q', 'w', 'e', ​​'r', 't', 'y', 'u', 'i', 'o', 'p';
int sz = sizeof (p)/sizeof (p [0]);
char q [sz];
für (int i = 0; iQ [i] = ";

Hier ist das angegebene Array p und das zweite Array ist q. Dieser Code kann in der Hauptfunktion sein. In C/C ++ ist das Standardcharakter "und kein Speicherplatz ("). Da der G ++ - Compiler die Zuordnung von "zu Q [i] nicht zulassen würde, wurde der Einzelraum (") zugewiesen.

Beachten Sie, dass die Standardwerte für Array Q -Elemente für das vollständige Mergesort -Programm nicht wirklich erforderlich sind, da sie weiterhin von den interessierenden Elementen überschrieben werden. SZ ausreicht, Array Q mit seiner Größe zu deklarieren.

Der Satz 'q', 'w', 'e', ​​'r', 't', 'y', 'u', 'i', 'o', 'P' wird verwendet, um zu erklären, wie Mergesort wird in diesem Abschnitt praktisch erreicht. In diesem Artikel wurde das Angeben von Array Q -Standardwerten als zusätzliches Wissen unterrichtet.

Das Set ist in die beiden Sätze unterteilt:

'Q', 'w', 'e', ​​'r', 't' und 'y', 'u', 'i', 'o', 'P'

Der obige Zusammenführungs-/Sortiercode wird als Funktion aufgerufen, aber das Sortieren und Zusammenführen finden nicht statt. Im realen Programm werden zuerst die Sortierung und Verschmelzung dieser beiden Läufe im Speicher aufgezeichnet. Die Sortierung und Verschmelzung wird letztendlich nicht unbedingt bei diesen beiden besonderen Anordnung von Charakteren durchgeführt.

Die obigen zwei Teilmengen sind jeweils weiter in zwei Teile aufgeteilt, um zu haben:

'Q', 'w', 'e' und 'r', 't' und 'y', 'u', 'i' und 'O', 'P'

Beachten Sie, dass für jede neue Abteilung hier die linke Teilmenge länger als die rechte Teilmenge nach einer Einheit ist.

Der obige Zusammenführungs-/Sortiercode wird als Funktion für aufeinanderfolgende Paare dieser neuen Teilmengen bezeichnet. Aber das Sortieren und Zusammenführen findet nicht sofort statt. Die Sortierung und Verschmelzung dieser aufeinanderfolgenden Läufpaare werden im Speicher des Computers aufgezeichnet. Die Sortierung und Verschmelzung wird letztendlich nicht unbedingt auf die besondere Anordnung von Charakteren dieser aufeinanderfolgenden Läufpaare erfolgen.

Die obigen Teilmengen sind jeweils weiter in zwei aufgeteilt, um zu haben:

'Q', 'w' und 'e' und 'r' und 't' und 'y', 'u' und 'i' und 'o' und 'P'

Die Sortierung und Verschmelzung aufeinanderfolgender Paare wird aufgezeichnet.

Hier können einige Untergruppen nicht mehr geteilt werden, weil sie jeweils aus einem Element bestehen. Dann führen die Aufteilung der oben genannten Absenkung von mehr als einer Länge zu:

'Q' und 'w' und 'e' und 'r' und 't' und 'y' und 'u' und 'i' und '' ' O ' und ' p '

Die Sortierung und Verschmelzung aufeinanderfolgender Paare wird aufgezeichnet.

Die Sortier- und Zusammenführungsfunktion wird rekursiv codiert. Und so wird es in der umgekehrten Reihenfolge einberufen, die für die oft aufgezeichnet wurde, wurde es aufgezeichnet.

Also wird 'q' und 'w' sortiert und in 'q', 'w' zusammengeführt und verschmolzen. 'E' und 'r' werden sortiert und in 'e', 'r' zusammengeführt. 'T'. 'Y' wird sortiert und in 't', 'y' sortiert und zusammengeführt. 'U' und 'i' werden sortiert und in 'i', 'u' zusammengefasst. 'Ö'. 'P' wird sortiert und in 'o', 'p' zusammengeführt. Die obige Zusammenführungs- und Sortierfunktion wird hier verwendet. und es wird durchgehend verwendet.

Weiter: 'q', 'w' und 'e', 'r' wird sortiert und in 'e', 'q', 'r', 'w' sortiert und zusammengeführt. 'T', 'y' und 'i', 'u' wird sortiert und zusammengeführt, 'i', 't', 'u', 'y'. Zu diesem Zeitpunkt wird 'o', 'p' nicht mit früheren Teilmengen von zwei Teilmengen verbunden. Die obige Zusammenführungs- und Sortierfunktion wurde hier verwendet und wird durchgehend verwendet.

Die nächste Stufe: 'e', 'q', 'r', 'w' und 'i', 't', 'u', 'y' werden sortiert und in 'e', ',', ',', ',' Ich ',' Q ',' R ',' T ',' u ',' W ',' Y '. Zu diesem Zeitpunkt wird 'o', 'p' erneut mit keinem der vorherigen Teilmengen verbunden.

Die letzte Stufe: 'e', 'i', 'q', 'r', 't', 'u', 'W', 'Y' und 'o', p ' werden sortiert und verschmolzen in 'e', 'i', 'o', 'p', 'q', 'r', 't', 'u', 'w', 'y'. Das ungeortierte Set wurde sortiert.

Codierung von Mersort in C

Die Aufgabe besteht darin, Array P zu sortieren und nicht Array Q. Für das gesamte Mergesort -Programm wird Array Q zuerst eine Kopie von Array P erstellt. Das Programm sortiert dann Array q in Array p. Dies ist nicht ganz das, was oben unterstellt ist. Es gibt vier Funktionen für das vollständige Mergesort -Programm.

Die Funktion zu teilen und zu verschmelzen

Dies ist die Hauptfunktion im Programm. Erinnern Sie sich daran, dass das Zusammenführen auch die Sortierung der linken und rechten aufeinanderfolgenden Läufe beinhaltet. Diese Verschmelzung ist in Erinnerung und beginnt tatsächlich, wenn das Array durch zwei, zwei und zwei usw. geteilt wurde. Bis es nur ein Element pro Lauf gibt. Sortieren und Zusammenführen beginnen also in dieser Phase mit einem Paar für ein Element pro Lauf. Das Skelett der Sortierfunktion lautet:

void topdownSplitmerge (char q [], int ibegin, int iend, char p [])
| |
// Teilen Sie die Teilmenge länger als 1 Element in zwei
int iMiddle = (iBegin + iend) / 2; // Imiddle ist der mittlere Punkt
| |
| |
| |
// Die resultierenden Teilmengen von Array Q [] in P [] zusammenführen
topdownmerge (Q, Ibegin, Imiddle, iend, p);

Diese Funktion nimmt das angegebene Array als q an, das in diesem Fall tatsächlich das Kopierarray Q ist. Es nimmt auch das Kopierarray als p, was in diesem Fall tatsächlich das angegebene Array P ist. Für den ersten Anruf dieser Funktion ist iBegin = 0 und iend = n, wobei n die Größe beider Arrays hat. Diese sind an der null-indexierten Beschäftigung des Arrays zurückzuführen.

Nach einer Division von zwei wird iBegin der erste Index des linken Laufs sein und Iend wird der letzte Index der aufeinanderfolgenden rechten Lauf sein. Die Abteilung von zwei gibt die Ganzzahl Imiddle und ignoriert den Rest. Dies ist der letzte Index des linken Laufs und auch der erste Index des rechten Laufs. Diese Mehrdeutigkeit wird durch die Zeit des Sortiercodes beseitigt.

Die letzte Aussage im obigen Code ist ein Aufruf der genauen Funktions- und Sortierfunktion. Dieser Anruf geht an den Speicher, wenn er aufgerufen wird. Es wird für alle seine Anrufe in umgekehrter Reihenfolge ausgeführt, da es sich um einen rekursiven Anruf handelt. Es nimmt die Variablen als Argumente an. Q, Ibegin, Iend und P, empfangen von der äußeren codierten Funktion. Imiddle, das auch eines seiner Argumente ist, wird in der äußeren codierten Funktion über dem Aufruf erstellt.

In dieser äußeren codierten Funktion befindet sich die linke und rechte Läufe identifiziert (geteilt). Dies geschieht am besten, indem ein rekursiver Aufruf der äußeren codierten Funktion wie folgt getätigt wird (ein Code, das in die Funktionsdefinition enthalten ist):

void topdownSplitmerge (char q [], int ibegin, int iend, char p [])
// Teilen Sie die Teilmenge länger als 1 Element in zwei
int iMiddle = (iBegin + iend) / 2; // Imiddle ist der mittlere Punkt
// beide Läufe von Array A [] in b [] rekursiv sortieren, rekursiv sortieren
TopDownSplitmerge (P, Ibegin, Imiddle, q); // Nach dem Auswendiglernen die linke Teilmenge in zwei zum Sortieren unterscheiden
topdownSplitmerge (P, Imiddle, iend, q); // Die rechte Teilmenge in zwei zum Sortieren nach dem Auswendiglernen unterteilen
// Die resultierenden Teilmengen von Array Q [] in P [] zusammenführen
topdownmerge (Q, Ibegin, Imiddle, iend, p);

Die beiden neuen rekursiven Anrufe wurden über den rekursiven Aufruf von TopdownMerge () eingegeben. Diese beiden Anrufe werden zusammen mit TopdownMerge () auswendig gelernt und so oft nach Bedarf in umgekehrter Reihenfolge bezeichnet.

Wenn das angegebene Array kein Element hat, sollte es keine Sortierung geben. Wenn die Anzahl der Elemente im angegebenen Array 1 ist, ist das Array bereits sortiert, und es sollte keine Sortierung stattfinden. Dies wird durch eine Anweisung im Inneren erfüllt, jedoch oben in der äußeren codierten Funktion, TopdownSplitmerge () wie folgt:

void topdownSplitmerge (char q [], int ibegin, int iend, char p [])
if (iend - iBegin<= 1)
zurückkehren;
int iMiddle = (iBegin + iend) / 2;
TopDownSplitmerge (P, Ibegin, Imiddle, q);
topdownSplitmerge (P, Imiddle, iend, q);
topdownmerge (Q, Ibegin, Imiddle, iend, p);

Die genaue Funktion zum Zusammenführen und Sortieren

Der Name dieser Funktion lautet TopdownMerge (). Es wird rekursiv von TopDownSplitmerge () bezeichnet. Der Code ist:

void topdownmerge (char p [], int ibegin, int iMiddle, int iend, char q [])
// Während es Elemente in den linken oder rechten Teilmengen gibt…
int i = iBegin;
int j = Imiddle;
für (int k = iBegin; k if (i = iend || p [i] <= P[j]))
Q [k] = P [i];
i = i + 1;
anders
Q [k] = P [j];
J = J + 1;


Theoretisch iteriert diese Funktion vom Beginn des linken Laufs (Teilmenge) bis zum Ende des rechten Laufs (Teilmenge). Beachten.

Einmales Kopie für alle Elemente machen

Zu Beginn des Programms wurde nach der folgenden Funktion (in diesem Abschnitt) alle Elemente des angegebenen Arrays in das Array kopiert, q, q. Der Code dafür ist:

void CopyArray (char p [], int iBegin, int iend, char q [])
für (int i = ibegin; ichQ [i] = P [i];

Es wird einmal aus der folgenden Funktion aufgerufen. Dies dauert als Argumente, das angegebene Array, P, dann 0, dann N und das andere Array Q, das theoretisch leer ist, aber bereits die gleiche Anzahl von Elementen wie P hat wie P. Iend, der hier die gleiche ist, ist die Länge des ursprünglich angegebenen Arrays.

Funktionieren Sie das Programm, um das Programm zu starten

Die Funktion, das Programm zu starten, lautet:

void topdownMergensort (char p [], char q [], int n)
CopyArray (p, 0, n, q); // p [] wird einmal in Q [] kopiert
topdownSplitmerge (q, 0, n, p);

Es ruft die Funktion copyArray () mit den erwarteten Argumenten auf. Es ruft als nächstes die Hauptfunktion TopdownSplitmerge () auf, wobei die Positionen der Arrays P und Q getauscht werden. Aus diesem Grund werden sortierte Werte im TopDownMerge () -Codel an Q und nicht an p gesendet.

Codeanordnung

Wenn die oben genannten vier codierten Funktionen in der folgenden Reihenfolge eingegeben werden,

- void topdownmerge ()

- void topdownSplitmerge ()

- CopyArray ()

- TopdownMergeNeort ()

Dann funktioniert das Mergesort -Programm (bestehend hauptsächlich aus diesen vier Funktionen) in einem C -Compiler ohne Probleme.

C Hauptfunktion

Eine geeignete C -Hauptfunktion für dieses Programm ist:

int main (int argc, char ** argv)

char p [] = 'q', 'w', 'e', ​​'r', 't', 'y', 'u', 'i', 'o', 'p';
int sz = sizeof (p)/sizeof (p [0]);
char q [sz];
für (int i = 0; iQ [i] = ";
Topdownmergersort (P, Q, SZ);
für (int i = 0; iprintf ("%c", p [i]);
printf ("\ n");
Rückkehr 0;

Abschluss

Teilen und erobern Sie den Algorithmus, das das Problem in kleinere Stücke unterteilt, mit der Hoffnung, sie unabhängig zu lösen. Nachdem alle kleineren Teile gelöst wurden, werden ihre Lösungen zu einer Hauptlösung kombiniert. Mit Merge-Sort gibt es eine kontinuierliche Aufteilung um zwei, bis jede Teilmenge ein Element lang ist und automatisch bereits sortiert ist. Das Zusammenbringen dieser einzelnen Elemente beinhaltet rekursive Funktionen und die tatsächliche Sortierung, beginnend mit Paaren einzelner Elemente.