2017-04-10 2 views
1

Ich habe eine kleine Überarbeitung der Sortieralgorithmen gemacht und kam mit Merge Sort. Ich habe meinen Code geschrieben und habe ihn in der letzten Stunde modifiziert, um festzustellen, warum er nicht funktioniert. Ich bekomme Standard StackOverFlow Exception. Kann mir jemand sagen, was mit dem Algorithmus nicht stimmt? Danke im Voraus. Hier ist, was ich haben es geschafft, so weit zu schreiben:Einfache Zusammenführung Sortieren in C#

public Int32[] MergeSort(Int32[] array) 
{ 
    int counter = 0; 
    if (array.Length == 0) { return array; } 
    int mid = array.Length/2; 
    Int32[] leftHalf = new Int32[mid+1]; 
    Int32[] rightHalf = new Int32[mid+1]; 
    for (int i = 0; i < mid; i++) { 
     leftHalf[i] = array[i]; 
    } 
    for (int j = mid; j < array.Length; j++) { 
     rightHalf[counter] = array[j]; 
     counter++; 
    } 
    counter = 0; 
    MergeSort(leftHalf); 
    MergeSort(rightHalf); 
    return SortAndMerge(leftHalf,rightHalf); 
} 

public Int32[] SortAndMerge(Int32[] left, Int32[] right) { 
    Int32[] myResult = new Int32[left.Length+right.Length]; 
    while (left.Length > 0 || right.Length > 0) { 
     if (left.Length > 0 && right.Length > 0) 
     { 
      if (left[0] <= right[0]) 
      { 
       myResult[myResult.Length] = left[0]; 
       int toRemoveIndex = Array.IndexOf(left, left[0]); 
       left = left.Where((x, y) => y != toRemoveIndex).ToArray(); 
      } 
      else 
      { 
       myResult[myResult.Length] = right[0]; 
       int toRemoveIndex = Array.IndexOf(right, right[0]); 
       right = right.Where((z, g) => g != toRemoveIndex).ToArray(); 
      } 

     } 
     else if (left.Length > 0) 
     { 
      myResult[myResult.Length] = left[0]; 
      int toRemoveIndex = Array.IndexOf(left, left[0]); 
      left = left.Where((x, y) => y != toRemoveIndex).ToArray(); 
     } 
     else if (right.Length > 0) { 
      myResult[myResult.Length] = right[0]; 
      int toRemoveIndex = Array.IndexOf(right, right[0]); 
      right = right.Where((x, y) => y != toRemoveIndex).ToArray(); 
     } 
    } 
    return myResult; 
} 
+0

Können Sie erklären, was 'counter' in der' MergeSort' Funktion macht? ... Ich meine ich weiß was es bewirkt, aber warum nicht 'rightHalf [j - mid]' anstelle von 'rightHalf [counter] '... könnte es klarer machen? –

+0

Tut mir leid, Rustam zu fragen, aber mit so vielen verschachtelten If's, ist das wirklich nötig? Bevor wir uns einmal anschauen, warum es einen SO-Fehler gibt, sollten wir, wenn wir diese verschachtelten ifs loswerden, als Teil meiner Überarbeitung von Algorithmen sehen, ob Algorithmen tatsächlich solche Haltungen erfordern. – Arjang

+0

Der Debugger gibt Ihnen einen Stack-Trace und Sie können den Code Zeile für Zeile durchlaufen. Das würde Ihnen eine Menge Informationen darüber geben, was gerade auf den ewigen Schleifen passiert. –

Antwort

2
if (array.Length == 0) return; 

Diese nie wahr ist, also die Ausnahme, weil Sie immer Array wie folgt erstellen.

Int32[] leftHalf = new Int32[mid+1]; 

Die Mindestlänge beträgt 1.

hier richtig merge Sortieralgorithmus Check-out.

https://en.wikipedia.org/wiki/Merge_sort#Algorithm

+0

Das ist richtig –

+0

Korrekt, aber danke, aber es löst das Problem nicht. –

1

Haben Sie Refactoring etwas dagegen? Warum zip nicht hier die Probe von Msdn

int[] numbers = { 1, 2, 3, 4 }; 
string[] words = { "one", "two", "three" }; 
var numbersAndWords = numbers.Zip(words, (first, second) => first + " " + second); 
foreach (var item in numbersAndWords) 
Console.WriteLine(item); 

Dieser Code erzeugt die folgende Ausgabe:

1 ein

2 zwei

3 drei

Es ist auch Linq für die Sortierung.

+0

Ich erwäge die Implementierung von merge sort, deshalb funktioniert ZIP nicht für mich. Trotzdem danke. –