これは宿題ではありません。学校に通うお金がないので、高速道路の料金所でシフトを組みながら独学しています (顧客が少ない長い夜)。
私は単純な「マージソート」を実装しようとしていました。最初に考え、実際の学習が必要な場合は頭を少し伸ばしてから、使用しているマニュアルの解決策を見てください: "2008-08-21 | アルゴリズムの設計マニュアル | スプリンガー | Steven S. Skiena | ISBN-1848000693".
配列をバッファーとして使用して「マージ」ステップを実装するソリューションを思いついたので、以下に貼り付けます。著者はキューを使用しているので、次のように思います。
- 代わりにキューを使用する必要がありますか?
- ある方法と他の方法の利点は何ですか? (彼はトップアルゴリズムであり、私は初心者なので、明らかに彼の方法の方が優れていますが、その長所を正確に特定することはできません。助けてください)
- 彼の選択を支配したトレードオフ/仮定は何ですか?
これが私のコードです(完全を期すために分割機能の実装も含めていますが、merge
ここではステップを確認しているだけだと思います。私の質問は具体的であるため、これはコードレビューの投稿ではないと思います1 つのメソッドだけに、および別のメソッドと比較したそのパフォーマンスについて):
package exercises;
public class MergeSort {
private static void merge(int[] values, int leftStart, int midPoint,
int rightEnd) {
int intervalSize = rightEnd - leftStart;
int[] mergeSpace = new int[intervalSize];
int nowMerging = 0;
int pointLeft = leftStart;
int pointRight = midPoint;
do {
if (values[pointLeft] <= values[pointRight]) {
mergeSpace[nowMerging] = values[pointLeft];
pointLeft++;
} else {
mergeSpace[nowMerging] = values[pointRight];
pointRight++;
}
nowMerging++;
} while (pointLeft < midPoint && pointRight < rightEnd);
int fillFromPoint = pointLeft < midPoint ? pointLeft : pointRight;
System.arraycopy(values, fillFromPoint, mergeSpace, nowMerging,
intervalSize - nowMerging);
System.arraycopy(mergeSpace, 0, values, leftStart, intervalSize);
}
public static void mergeSort(int[] values) {
mergeSort(values, 0, values.length);
}
private static void mergeSort(int[] values, int start, int end) {
int intervalSize = end - start;
if (intervalSize < 2) {
return;
}
boolean isIntervalSizeEven = intervalSize % 2 == 0;
int splittingAdjustment = isIntervalSizeEven ? 0 : 1;
int halfSize = intervalSize / 2;
int leftStart = start;
int rightEnd = end;
int midPoint = start + halfSize + splittingAdjustment;
mergeSort(values, leftStart, midPoint);
mergeSort(values, midPoint, rightEnd);
merge(values, leftStart, midPoint, rightEnd);
}
}
教科書の参照ソリューションは次のとおりです(Cにあるため、タグを追加しています)
merge(item_type s[], int low, int middle, int high)
{
int i; /* counter */
queue buffer1, buffer2; /* buffers to hold elements for merging */
init_queue(&buffer1);
init_queue(&buffer2);
for (i=low; i<=middle; i++) enqueue(&buffer1,s[i]);
for (i=middle+1; i<=high; i++) enqueue(&buffer2,s[i]);
i = low;
while (!(empty_queue(&buffer1) || empty_queue(&buffer2))) {
if (headq(&buffer1) <= headq(&buffer2))
s[i++] = dequeue(&buffer1);
else
s[i++] = dequeue(&buffer2);
}
while (!empty_queue(&buffer1)) s[i++] = dequeue(&buffer1);
while (!empty_queue(&buffer2)) s[i++] = dequeue(&buffer2);
}