Common Algorithms
Merge Sort
Merge sort divides an array into smaller pieces, sorts those pieces, and merges the sorted pieces back together. The divide-and-conquer structure gives predictable O(n log n) performance.
Basic Implementation
Basic.java
Replay: real traced execution (multi-file project)
import java.util.Arrays;
public class Basic {
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
public static void merge(int[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
int[] leftArr = new int[n1];
int[] rightArr = new int[n2];
for (int i = 0; i < n1; i++)
leftArr[i] = arr[left + i];
for (int j = 0; j < n2; j++)
rightArr[j] = arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i] <= rightArr[j]) {
arr[k++] = leftArr[i++];
} else {
arr[k++] = rightArr[j++];
}
}
while (i < n1) arr[k++] = leftArr[i++];
while (j < n2) arr[k++] = rightArr[j++];
}
public static void main(String[] args) {
int[] numbers = {38, 27, 43, 3, 9, 82, 10};
System.out.println("Before: " + Arrays.toString(numbers));
mergeSort(numbers, 0, numbers.length - 1);
System.out.println("After: " + Arrays.toString(numbers));
}
}
public static void main(String[] args)
31}32public static void main(String[] args) {33 int[] numbers = {38, 27, 43, 3, 9, 82, 10};3435 System.out.println("Before: " + Arrays.toString(numbers));36 mergeSort(numbers, 0, numbers.length7 - 1);37 System.out.println("After: " + Arrays.toString(numbers));outputBefore: [38, 27, 43, 3, 9, 82, 10]public static void mergeSort(int[] arr, int left, int right)
pass 1 of 133public class Basic {4 public static void mergeSort(int[] arr, int left0, int right6) {5 if (left < right) {13 passes — pass 1 is the card above pass leftrightmid1 0 6 — 2 0 3 — 3 0 1 — 4 0 0 0 5 1 1 0 6 2 3 — 7 2 2 2 8 3 3 2 9 4 6 — ⋯ 2 more passes ⋯ 12 5 5 4 13 6 6 5 mid ← 3
pass 1 of 64public static void mergeSort(int[] arr, int left, int right) {5 if (left0 < right6) {6 int mid→ 3 = left0 + (right6 - left) / 2;7 mergeSort(arr, left0, mid3);8 mergeSort(arr, mid + 1, right);All 6 passes — pass 1 is the card above pass leftrightmid1 0 6 3 2 0 3 1 3 0 1 0 4 2 3 2 5 4 6 5 6 4 5 4 n1 ← 1, n2 ← 1
pass 1 of 611}12public static void merge(int[] arr, int left0, int mid0, int right1) {13 int n1→ 1 = mid0 - left0 + 1;14 int n2→ 1 = right1 - mid0;15 int[] leftArr = new int[n1];16 int[] rightArr = new int[n2];17 for (int i = 0; i < n1; i++)All 6 passes — pass 1 is the card above pass leftmidrightn1n21 0 0 1 1 1 2 2 2 3 1 1 3 0 1 3 2 2 4 4 4 5 1 1 5 4 5 6 2 1 6 0 3 6 4 3 leftArr[i] ← 38
pass 1 of 1116int[] rightArr = new int[n2];17for (int i0 = 0; i < n11; i++)18 leftArr[i]→ 38 = arr[left + i]38;19for (int j = 0; j < n2; j++)All 11 passes — pass 1 is the card above pass in1arr[left + i]leftleftArr[i]1 0 1 38 0 0 → 38 2 0 1 43 2 0 → 43 3 0 2 27 0 0 → 27 4 1 2 38 0 0 → 38 5 0 1 9 4 0 → 9 6 0 2 9 4 0 → 9 7 1 2 82 4 0 → 82 8 0 4 3 0 0 → 3 9 1 4 27 0 0 → 27 10 2 4 38 0 0 → 38 11 3 4 43 0 0 → 43 rightArr[j] ← 27
pass 1 of 918 leftArr[i] = arr[left + i];19for (int j0 = 0; j < n21; j++)20 rightArr[j]→ 27 = arr[mid + 1 + j]27;21int i = 0, j = 0, k = left;All 9 passes — pass 1 is the card above pass jn2arr[mid + 1 + j]midrightArr[j]1 0 1 27 0 0 → 27 2 0 1 3 2 0 → 3 3 0 2 3 1 0 → 3 4 1 2 43 1 0 → 43 5 0 1 82 4 0 → 82 6 0 1 10 5 0 → 10 7 0 3 9 3 0 → 9 8 1 3 10 3 0 → 10 9 2 3 82 3 0 → 82 k ← 0
20 rightArr[j] = arr[mid + 1 + j];21int i = 0, j = 0, k→ 0 = left;22while (i < n1 && j < n2) {while (i < n1 && j < n2)
pass 1 of 1421int i = 0, j = 0, k = left;22while (i0 < n11 && j0 < n21) {23 if (leftArr[i] <= rightArr[j]) {14 passes — pass 1 is the card above pass in1jn21 0 1 0 1 2 0 1 0 1 3 0 2 0 2 4 0 2 1 2 5 1 2 1 2 6 0 1 0 1 7 0 2 0 1 8 1 2 0 1 9 0 4 0 3 ⋯ 3 more passes ⋯ 13 2 4 2 3 14 3 4 2 3 k ← 1, j ← 1
pass 1 of 624 arr[k++] = leftArr[i++];25} else {26 arr[k→ 1++] = rightArr[j→ 1++];27}All 6 passes — pass 1 is the card above pass kj1 0 → 1 0 → 1 2 2 → 3 0 → 1 3 0 → 1 0 → 1 4 5 → 6 0 → 1 5 1 → 2 0 → 1 6 2 → 3 1 → 2 k ← 2, i ← 1, left ← 0, mid ← 1
pass 1 of 36 int mid = left + (right - left) / 2;7 mergeSort(arr, left→ 0, mid→ 1);8 mergeSort(arr, mid1 + 1, right3);9 merge(arr, left0, mid0, right1);10 }11}12public static void merge(int[] arr, int left, int mid, int right) {13 int n1 = mid - left + 1;14 int n2 = right - mid;15 int[] leftArr = new int[n1];16 int[] rightArr = new int[n2];17 for (int i = 0; i < n1; i++)18 leftArr[i] = arr[left + i];19 for (int j = 0; j < n2; j++)20 rightArr[j] = arr[mid + 1 + j];21 int i = 0, j = 0, k = left;22 while (i < n1 && j < n2) {23 if (leftArr[i] <= rightArr[j]) {24 arr[k++] = leftArr[i++];25 } else {26 arr[k++] = rightArr[j++];27 }28 }29 while (i0 < n11) arr[k→ 2++] = leftArr[i++];30 while (j < n2) arr[k++] = rightArr[j++];All 3 passes — pass 1 is the card above pass n1kileftmidright1 1 1 → 2 0 → 1 0 0 → 1 1 2 1 3 → 4 0 → 1 0 1 3 3 2 6 → 7 1 → 2 0 3 6 k ← 2
20 rightArr[j] = arr[mid + 1 + j];21int i = 0, j = 0, k→ 2 = left;22while (i < n1 && j < n2) {k ← 0
20 rightArr[j] = arr[mid + 1 + j];21int i = 0, j = 0, k→ 0 = left;22while (i < n1 && j < n2) {k ← 2, i ← 1
pass 1 of 822while (i < n1 && j < n2) {23 if (leftArr[i]27 <= rightArr[j]43) {24 arr[k→ 2++] = leftArr[i→ 1++];25 } else {All 8 passes — pass 1 is the card above pass leftArr[i]rightArr[j]jki1 27 43 1 1 → 2 0 → 1 2 38 43 1 2 → 3 1 → 2 3 9 82 0 4 → 5 0 → 1 4 9 10 0 4 → 5 0 → 1 5 3 9 0 0 → 1 0 → 1 6 27 82 2 3 → 4 1 → 2 7 38 82 2 4 → 5 2 → 3 8 43 82 2 5 → 6 3 → 4 k ← 4, j ← 2, left ← 0, mid ← 3
pass 1 of 36 int mid = left + (right - left) / 2;7 mergeSort(arr, left→ 0, mid→ 3);8 mergeSort(arr, mid3 + 1, right6);9 merge(arr, left0, mid1, right3);10 }11}12public static void merge(int[] arr, int left, int mid, int right) {13 int n1 = mid - left + 1;14 int n2 = right - mid;15 int[] leftArr = new int[n1];16 int[] rightArr = new int[n2];17 for (int i = 0; i < n1; i++)18 leftArr[i] = arr[left + i];19 for (int j = 0; j < n2; j++)20 rightArr[j] = arr[mid + 1 + j];21 int i = 0, j = 0, k = left;22 while (i < n1 && j < n2) {23 if (leftArr[i] <= rightArr[j]) {24 arr[k++] = leftArr[i++];25 } else {26 arr[k++] = rightArr[j++];27 }28 }29 while (i < n1) arr[k++] = leftArr[i++];30 while (j1 < n22) arr[k→ 4++] = rightArr[j++];31}All 3 passes — pass 1 is the card above pass n2rightkjleftmid1 2 3 3 → 4 1 → 2 0 1 → 3 2 1 5 5 → 6 0 → 1 4 4 → 5 3 3 6 6 → 7 2 → 3 0 3 k ← 4
20 rightArr[j] = arr[mid + 1 + j];21int i = 0, j = 0, k→ 4 = left;22while (i < n1 && j < n2) {k ← 4
20 rightArr[j] = arr[mid + 1 + j];21int i = 0, j = 0, k→ 4 = left;22while (i < n1 && j < n2) {k ← 0
20 rightArr[j] = arr[mid + 1 + j];21int i = 0, j = 0, k→ 0 = left;22while (i < n1 && j < n2) {mergeSort(numbers, 0, numbers.length - 1);
35 System.out.println("Before: " + Arrays.toString(numbers));36 mergeSort(numbers, 0, numbers.length7 - 1);37 System.out.println("After: " + Arrays.toString(numbers));38}outputAfter: [3, 9, 10, 27, 38, 43, 82]
Divide and Conquer
A problem-solving strategy that breaks a problem into smaller subproblems, solves them independently, and combines the results.
Tracing the Algorithm
The trace shows the recursive divide phase followed by the merge phase.
Trace.java
Replay: real traced execution (multi-file project)
import java.util.Arrays;
public class Trace {
private static int depth = 0;
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
indent();
System.out.println("Divide: " + arrayRange(arr, left, right));
depth++;
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
depth--;
indent();
System.out.println("Merged: " + arrayRange(arr, left, right));
}
}
public static void merge(int[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
int[] leftArr = new int[n1];
int[] rightArr = new int[n2];
for (int i = 0; i < n1; i++)
leftArr[i] = arr[left + i];
for (int j = 0; j < n2; j++)
rightArr[j] = arr[mid + 1 + j];
indent();
System.out.println(" Merge " + Arrays.toString(leftArr) +
" and " + Arrays.toString(rightArr));
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i] <= rightArr[j]) {
arr[k++] = leftArr[i++];
} else {
arr[k++] = rightArr[j++];
}
}
while (i < n1) arr[k++] = leftArr[i++];
while (j < n2) arr[k++] = rightArr[j++];
}
private static void indent() {
for (int i = 0; i < depth; i++) System.out.print(" ");
}
private static String arrayRange(int[] arr, int left, int right) {
int[] range = new int[right - left + 1];
for (int i = 0; i < range.length; i++)
range[i] = arr[left + i];
return Arrays.toString(range);
}
public static void main(String[] args) {
int[] numbers = {5, 2, 8, 1, 9};
System.out.println("Initial: " + Arrays.toString(numbers));
System.out.println();
mergeSort(numbers, 0, numbers.length - 1);
System.out.println();
System.out.println("Final: " + Arrays.toString(numbers));
}
}
import java.util.Arrays;
public class Trace {
private static int depth = 0;
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
indent();
System.out.println("Divide: " + arrayRange(arr, left, right));
depth++;
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
depth--;
indent();
System.out.println("Merged: " + arrayRange(arr, left, right));
}
}
public static void merge(int[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
int[] leftArr = new int[n1];
int[] rightArr = new int[n2];
for (int i = 0; i < n1; i++)
leftArr[i] = arr[left + i];
for (int j = 0; j < n2; j++)
rightArr[j] = arr[mid + 1 + j];
indent();
System.out.println(" Merge " + Arrays.toString(leftArr) +
" and " + Arrays.toString(rightArr));
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i] <= rightArr[j]) {
arr[k++] = leftArr[i++];
} else {
arr[k++] = rightArr[j++];
}
}
while (i < n1) arr[k++] = leftArr[i++];
while (j < n2) arr[k++] = rightArr[j++];
}
private static void indent() {
for (int i = 0; i < depth; i++) System.out.print(" ");
}
private static String arrayRange(int[] arr, int left, int right) {
int[] range = new int[right - left + 1];
for (int i = 0; i < range.length; i++)
range[i] = arr[left + i];
return Arrays.toString(range);
}
public static void main(String[] args) {
int[] numbers = {4, 1, 3, 2};
System.out.println("Initial: " + Arrays.toString(numbers));
System.out.println();
mergeSort(numbers, 0, numbers.length - 1);
System.out.println();
System.out.println("Final: " + Arrays.toString(numbers));
}
}
import java.util.Arrays;
public class Trace {
private static int depth = 0;
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
indent();
System.out.println("Divide: " + arrayRange(arr, left, right));
depth++;
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
depth--;
indent();
System.out.println("Merged: " + arrayRange(arr, left, right));
}
}
public static void merge(int[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
int[] leftArr = new int[n1];
int[] rightArr = new int[n2];
for (int i = 0; i < n1; i++)
leftArr[i] = arr[left + i];
for (int j = 0; j < n2; j++)
rightArr[j] = arr[mid + 1 + j];
indent();
System.out.println(" Merge " + Arrays.toString(leftArr) +
" and " + Arrays.toString(rightArr));
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i] <= rightArr[j]) {
arr[k++] = leftArr[i++];
} else {
arr[k++] = rightArr[j++];
}
}
while (i < n1) arr[k++] = leftArr[i++];
while (j < n2) arr[k++] = rightArr[j++];
}
private static void indent() {
for (int i = 0; i < depth; i++) System.out.print(" ");
}
private static String arrayRange(int[] arr, int left, int right) {
int[] range = new int[right - left + 1];
for (int i = 0; i < range.length; i++)
range[i] = arr[left + i];
return Arrays.toString(range);
}
public static void main(String[] args) {
int[] numbers = {9, 7, 5, 3, 1};
System.out.println("Initial: " + Arrays.toString(numbers));
System.out.println();
mergeSort(numbers, 0, numbers.length - 1);
System.out.println();
System.out.println("Final: " + Arrays.toString(numbers));
}
}
public static void main(String[] args)
61}62public static void main(String[] args) {63 int[] numbers = {5, 2, 8, 1, 9}; //@numbers={5, 2, 8, 1, 9}, {4, 1, 3, 2}, {9, 7, 5, 3, 1}6465 System.out.println("Initial: " + Arrays.toString(numbers));66 System.out.println();67 mergeSort(numbers, 0, numbers.length5 - 1);68 System.out.println();outputInitial: [5, 2, 8, 1, 9]public static void mergeSort(int[] arr, int left, int right)
pass 1 of 95private static int depth = 0;6public static void mergeSort(int[] arr, int left0, int right4) {7 if (left < right) {All 9 passes — pass 1 is the card above pass leftrightmid1 0 4 — 2 0 2 — 3 0 1 — 4 0 0 0 5 1 1 0 6 2 2 1 7 3 4 — 8 3 3 3 9 4 4 3 if (left < right)
pass 1 of 46public static void mergeSort(int[] arr, int left, int right) {7 if (left0 < right4) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left, right));All 4 passes — pass 1 is the card above pass leftright1 0 4 2 0 2 3 0 1 4 3 4 private static void indent()
pass 1 of 127 if (left < right) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left0, right4));10 depth++;1112 int mid = left + (right - left) / 2;1314 mergeSort(arr, left, mid);15 mergeSort(arr, mid + 1, right);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i = 0; i < depth; i++) System.out.print(" ");All 12 passes — pass 1 is the card above pass leftrightn1midkjidepth1 0 4 — — — — — — 2 — — — — — — — — 3 — — — — — — — — 4 0 1 1 0 0 → 1 0 → 1 0 → 1 3 → 2 5 — — — — — — — — 6 — — — — — — — — 7 — — — — — — — — 8 — — — — — — — — 9 — — — — — — — — 10 — — — — — — — — 11 — — — — 0 → 1 0 → 1 — — 12 0 4 — — — — — — private static String arrayRange(int[] arr, int left, int right)
pass 1 of 856private static String arrayRange(int[] arr, int left0, int right4) {57 int[] range = new int[right4 - left0 + 1];58 for (int i = 0; i < range.length; i++)All 8 passes — pass 1 is the card above pass leftright1 0 4 2 0 2 3 0 1 4 0 1 5 0 2 6 3 4 7 3 4 8 0 4 range[i] ← 5
pass 1 of 2457int[] range = new int[right - left + 1];58for (int i0 = 0; i < range.length5; i++)59 range[i]→ 5 = arr[left + i]5;60return Arrays.toString(range);24 passes — pass 1 is the card above pass irange.lengtharr[left + i]leftrange[i]1 0 5 5 0 0 → 5 2 1 5 2 0 0 → 2 3 2 5 8 0 0 → 8 4 3 5 1 0 0 → 1 5 4 5 9 0 0 → 9 6 0 3 5 0 0 → 5 7 1 3 2 0 0 → 2 8 2 3 8 0 0 → 8 9 0 2 5 0 0 → 5 ⋯ 13 more passes ⋯ 23 3 5 8 0 0 → 8 24 4 5 9 0 0 → 9 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 1, mid ← 2
8indent();9System.out.println("Divide: " + arrayRange(arr, left0, right4));10depth→ 1++;1112int mid→ 2 = left0 + (right4 - left) / 2;1314mergeSort(arr, left0, mid2);15mergeSort(arr, mid + 1, right);outputDivide: [5, 2, 8, 1, 9]for (int i = 0; i < depth; i++)
pass 1 of 167 if (left < right) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left0, right2));10 depth++;1112 int mid = left + (right - left) / 2;1314 mergeSort(arr, left, mid);15 mergeSort(arr, mid + 1, right);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i0 = 0; i < depth1; i++) System.out.print(" ");54}output16 passes — pass 1 is the card above pass leftrightn1midkjidepth1 0 2 — — — — 0 1 2 — — — — — — 0 2 3 0 1 — — — — 1 2 4 — — — — — — 0 3 5 — — — — — — 1 3 6 0 1 1 0 0 0 → 1 0 → 1 3 → 2 7 — — — — — — 0 2 8 0 1 — — — — 1 2 9 — — — — — — 0 2 ⋯ 5 more passes ⋯ 15 3 4 — — — — 0 1 16 — — — — 0 0 → 1 0 1 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 2, mid ← 1
8indent();9System.out.println("Divide: " + arrayRange(arr, left0, right2));10depth→ 2++;1112int mid→ 1 = left0 + (right2 - left) / 2;1314mergeSort(arr, left0, mid1);15mergeSort(arr, mid + 1, right);outputDivide: [5, 2, 8]return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 3, mid ← 0
8indent();9System.out.println("Divide: " + arrayRange(arr, left0, right1));10depth→ 3++;1112int mid→ 0 = left0 + (right1 - left) / 2;1314mergeSort(arr, left0, mid0);15mergeSort(arr, mid + 1, right);outputDivide: [5, 2]n1 ← 1, n2 ← 1
pass 1 of 423}24public static void merge(int[] arr, int left0, int mid0, int right1) {25 int n1→ 1 = mid0 - left0 + 1;26 int n2→ 1 = right1 - mid0;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];All 4 passes — pass 1 is the card above pass leftmidrightn1n21 0 0 1 1 1 2 0 1 2 2 1 3 3 3 4 1 1 4 0 2 4 3 2 leftArr[i] ← 5
pass 1 of 730for (int i0 = 0; i < n11; i++)31 leftArr[i]→ 5 = arr[left + i]5;32for (int j = 0; j < n2; j++)All 7 passes — pass 1 is the card above pass in1arr[left + i]leftleftArr[i]1 0 1 5 0 0 → 5 2 0 2 2 0 0 → 2 3 1 2 5 0 0 → 5 4 0 1 1 3 0 → 1 5 0 3 2 0 0 → 2 6 1 3 5 0 0 → 5 7 2 3 8 0 0 → 8 rightArr[j] ← 2
pass 1 of 531 leftArr[i] = arr[left + i];32for (int j0 = 0; j < n21; j++)33 rightArr[j]→ 2 = arr[mid + 1 + j]2;All 5 passes — pass 1 is the card above pass jn2arr[mid + 1 + j]midrightArr[j]1 0 1 2 0 0 → 2 2 0 1 8 1 0 → 8 3 0 1 9 3 0 → 9 4 0 2 1 2 0 → 1 5 1 2 9 2 0 → 9 indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +while (i < n1 && j < n2)
pass 1 of 839int i = 0, j = 0, k = left;40while (i0 < n11 && j0 < n21) {41 if (leftArr[i] <= rightArr[j]) {All 8 passes — pass 1 is the card above pass n1n2leftmidrightkjidepth1 1 1 0 0 1 0 → 1 0 → 1 0 → 1 3 → 2 2 2 1 — — — — 0 0 — 3 2 1 — — — — 0 1 — 4 1 1 — — — — 0 0 — 5 3 2 — — — 0 → 1 0 → 1 0 — 6 3 2 — — — — 1 0 — 7 3 2 — — — — 1 1 — 8 3 2 — — — — 1 2 — k ← 1, j ← 1
pass 1 of 242 arr[k++] = leftArr[i++];43} else {44 arr[k→ 1++] = rightArr[j→ 1++];45}k ← 2, i ← 1, depth ← 2
17 merge(arr, left0, mid0, right1);1819 depth→ 2--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i0 < n11) arr[k→ 2++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}left ← 0, mid ← 1
14 mergeSort(arr, left→ 0, mid→ 1);15 mergeSort(arr, mid1 + 1, right2);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left0, right1));22}outputMerged: [2, 5]indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +k ← 1, i ← 1
pass 1 of 640while (i < n1 && j < n2) {41 if (leftArr[i]2 <= rightArr[j]8) {42 arr[k→ 1++] = leftArr[i→ 1++];43 } else {All 6 passes — pass 1 is the card above pass leftArr[i]rightArr[j]jki1 2 8 0 0 → 1 0 → 1 2 5 8 0 1 → 2 1 → 2 3 1 9 0 3 → 4 0 → 1 4 2 9 1 1 → 2 0 → 1 5 5 9 1 2 → 3 1 → 2 6 8 9 1 3 → 4 2 → 3 k ← 3, j ← 1, depth ← 1
pass 1 of 317 merge(arr, left0, mid1, right2);1819 depth→ 1--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j0 < n21) arr[k→ 3++] = rightArr[j++];50}All 3 passes — pass 1 is the card above pass n2leftmidrightkjdepth1 1 0 1 2 2 → 3 0 → 1 2 → 1 2 1 3 3 4 4 → 5 0 → 1 2 → 1 3 2 0 2 4 4 → 5 1 → 2 1 → 0 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}left ← 0, mid ← 2
14 mergeSort(arr, left→ 0, mid→ 2);15 mergeSort(arr, mid2 + 1, right4);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left0, right2));22}outputMerged: [2, 5, 8]return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 2, mid ← 3
8indent();9System.out.println("Divide: " + arrayRange(arr, left3, right4));10depth→ 2++;1112int mid→ 3 = left3 + (right4 - left) / 2;1314mergeSort(arr, left3, mid3);15mergeSort(arr, mid + 1, right);outputDivide: [1, 9]indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}mid ← 2, right ← 4
14 mergeSort(arr, left, mid);15 mergeSort(arr, mid→ 2 + 1, right→ 4);1617 merge(arr, left0, mid2, right4);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left3, right4));22}outputMerged: [1, 9]indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +k ← 1, j ← 1
pass 2 of 242 arr[k++] = leftArr[i++];43} else {44 arr[k→ 1++] = rightArr[j→ 1++];45}return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}System.out.println("Merged: " + arrayRange(arr, left, right));
20 indent();21 System.out.println("Merged: " + arrayRange(arr, left0, right4));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i = 0; i < depth; i++) System.out.print(" ");54}5556private static String arrayRange(int[] arr, int left, int right) {57 int[] range = new int[right - left + 1];58 for (int i = 0; i < range.length; i++)59 range[i] = arr[left + i];60 return Arrays.toString(range);61}62public static void main(String[] args) {63 int[] numbers = {5, 2, 8, 1, 9}; //@numbers={5, 2, 8, 1, 9}, {4, 1, 3, 2}, {9, 7, 5, 3, 1}6465 System.out.println("Initial: " + Arrays.toString(numbers));66 System.out.println();67 mergeSort(numbers, 0, numbers.length5 - 1);68 System.out.println();69 System.out.println("Final: " + Arrays.toString(numbers));70}outputMerged: [1, 2, 5, 8, 9] Final: [1, 2, 5, 8, 9]
public static void main(String[] args)
61}62public static void main(String[] args) {63 int[] numbers = {4, 1, 3, 2};6465 System.out.println("Initial: " + Arrays.toString(numbers));66 System.out.println();67 mergeSort(numbers, 0, numbers.length4 - 1);68 System.out.println();outputInitial: [4, 1, 3, 2]public static void mergeSort(int[] arr, int left, int right)
pass 1 of 75private static int depth = 0;6public static void mergeSort(int[] arr, int left0, int right3) {7 if (left < right) {All 7 passes — pass 1 is the card above pass leftrightmid1 0 3 — 2 0 1 — 3 0 0 0 4 1 1 0 5 2 3 — 6 2 2 2 7 3 3 2 if (left < right)
pass 1 of 36public static void mergeSort(int[] arr, int left, int right) {7 if (left0 < right3) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left, right));All 3 passes — pass 1 is the card above pass leftright1 0 3 2 0 1 3 2 3 private static void indent()
pass 1 of 97 if (left < right) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left0, right3));10 depth++;1112 int mid = left + (right - left) / 2;1314 mergeSort(arr, left, mid);15 mergeSort(arr, mid + 1, right);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i = 0; i < depth; i++) System.out.print(" ");All 9 passes — pass 1 is the card above pass leftrightleftArr[i]rightArr[j]jki1 0 3 — — — — — 2 — — — — — — — 3 — — — — — — — 4 — — — — — — — 5 — — — — — — — 6 — — — — — — — 7 — — — — — — — 8 — — 1 2 0 0 → 1 0 → 1 9 0 3 — — — — — private static String arrayRange(int[] arr, int left, int right)
pass 1 of 656private static String arrayRange(int[] arr, int left0, int right3) {57 int[] range = new int[right3 - left0 + 1];58 for (int i = 0; i < range.length; i++)All 6 passes — pass 1 is the card above pass leftright1 0 3 2 0 1 3 0 1 4 2 3 5 2 3 6 0 3 range[i] ← 4
pass 1 of 1657int[] range = new int[right - left + 1];58for (int i0 = 0; i < range.length4; i++)59 range[i]→ 4 = arr[left + i]4;60return Arrays.toString(range);16 passes — pass 1 is the card above pass irange.lengtharr[left + i]leftrange[i]1 0 4 4 0 0 → 4 2 1 4 1 0 0 → 1 3 2 4 3 0 0 → 3 4 3 4 2 0 0 → 2 5 0 2 4 0 0 → 4 6 1 2 1 0 0 → 1 7 0 2 1 0 0 → 1 8 1 2 4 0 0 → 4 9 0 2 3 2 0 → 3 ⋯ 5 more passes ⋯ 15 2 4 3 0 0 → 3 16 3 4 4 0 0 → 4 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 1, mid ← 1
8indent();9System.out.println("Divide: " + arrayRange(arr, left0, right3));10depth→ 1++;1112int mid→ 1 = left0 + (right3 - left) / 2;1314mergeSort(arr, left0, mid1);15mergeSort(arr, mid + 1, right);outputDivide: [4, 1, 3, 2]for (int i = 0; i < depth; i++)
pass 1 of 97 if (left < right) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left0, right1));10 depth++;1112 int mid = left + (right - left) / 2;1314 mergeSort(arr, left, mid);15 mergeSort(arr, mid + 1, right);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i0 = 0; i < depth1; i++) System.out.print(" ");54}outputAll 9 passes — pass 1 is the card above pass depthleftrightleftArr[i]rightArr[j]jki1 1 0 1 — — — — 0 2 2 — — — — — — 0 3 2 — — — — — 0 1 4 1 0 1 — — — — 0 5 1 2 3 — — — — 0 6 2 — — — — — — 0 7 2 — — — — — 2 1 8 1 2 3 — — — — 0 9 1 — — 1 2 0 0 0 → 1 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 2, mid ← 0
8indent();9System.out.println("Divide: " + arrayRange(arr, left0, right1));10depth→ 2++;1112int mid→ 0 = left0 + (right1 - left) / 2;1314mergeSort(arr, left0, mid0);15mergeSort(arr, mid + 1, right);outputDivide: [4, 1]n1 ← 1, n2 ← 1
pass 1 of 323}24public static void merge(int[] arr, int left0, int mid0, int right1) {25 int n1→ 1 = mid0 - left0 + 1;26 int n2→ 1 = right1 - mid0;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];All 3 passes — pass 1 is the card above pass leftmidrightn1n21 0 0 1 1 1 2 2 2 3 1 1 3 0 1 3 2 2 leftArr[i] ← 4
pass 1 of 430for (int i0 = 0; i < n11; i++)31 leftArr[i]→ 4 = arr[left + i]4;32for (int j = 0; j < n2; j++)All 4 passes — pass 1 is the card above pass in1arr[left + i]leftleftArr[i]1 0 1 4 0 0 → 4 2 0 1 3 2 0 → 3 3 0 2 1 0 0 → 1 4 1 2 4 0 0 → 4 rightArr[j] ← 1
pass 1 of 431 leftArr[i] = arr[left + i];32for (int j0 = 0; j < n21; j++)33 rightArr[j]→ 1 = arr[mid + 1 + j]1;All 4 passes — pass 1 is the card above pass jn2arr[mid + 1 + j]midrightArr[j]1 0 1 1 0 0 → 1 2 0 1 2 2 0 → 2 3 0 2 2 1 0 → 2 4 1 2 3 1 0 → 3 indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +while (i < n1 && j < n2)
pass 1 of 539int i = 0, j = 0, k = left;40while (i0 < n11 && j0 < n21) {41 if (leftArr[i] <= rightArr[j]) {All 5 passes — pass 1 is the card above pass n1jn2leftArr[i]rightArr[j]ki1 1 0 1 — — — 0 2 1 0 1 — — — 0 3 2 0 2 1 2 0 → 1 0 → 1 4 2 0 2 — — — 1 5 2 1 2 — — — 1 k ← 1, j ← 1
pass 1 of 442 arr[k++] = leftArr[i++];43} else {44 arr[k→ 1++] = rightArr[j→ 1++];45}All 4 passes — pass 1 is the card above pass kj1 0 → 1 0 → 1 2 2 → 3 0 → 1 3 1 → 2 0 → 1 4 2 → 3 1 → 2 k ← 2, i ← 1, depth ← 1
pass 1 of 317 merge(arr, left0, mid0, right1);1819 depth→ 1--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i0 < n11) arr[k→ 2++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];All 3 passes — pass 1 is the card above pass n1leftmidrightkidepth1 1 0 0 1 1 → 2 0 → 1 2 → 1 2 1 2 2 3 3 → 4 0 → 1 2 → 1 3 2 0 1 3 3 → 4 1 → 2 1 → 0 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}left ← 0, mid ← 1
14 mergeSort(arr, left→ 0, mid→ 1);15 mergeSort(arr, mid1 + 1, right3);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left0, right1));22}outputMerged: [1, 4]return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 2, mid ← 2
8indent();9System.out.println("Divide: " + arrayRange(arr, left2, right3));10depth→ 2++;1112int mid→ 2 = left2 + (right3 - left) / 2;1314mergeSort(arr, left2, mid2);15mergeSort(arr, mid + 1, right);outputDivide: [3, 2]indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}mid ← 1, right ← 3
14 mergeSort(arr, left, mid);15 mergeSort(arr, mid→ 1 + 1, right→ 3);1617 merge(arr, left0, mid1, right3);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left2, right3));22}outputMerged: [2, 3]indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +k ← 1, i ← 1
40while (i < n1 && j < n2) {41 if (leftArr[i]1 <= rightArr[j]2) {42 arr[k→ 1++] = leftArr[i→ 1++];43 } else {values this step0jreturn Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}System.out.println("Merged: " + arrayRange(arr, left, right));
20 indent();21 System.out.println("Merged: " + arrayRange(arr, left0, right3));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i = 0; i < depth; i++) System.out.print(" ");54}5556private static String arrayRange(int[] arr, int left, int right) {57 int[] range = new int[right - left + 1];58 for (int i = 0; i < range.length; i++)59 range[i] = arr[left + i];60 return Arrays.toString(range);61}62public static void main(String[] args) {63 int[] numbers = {4, 1, 3, 2};6465 System.out.println("Initial: " + Arrays.toString(numbers));66 System.out.println();67 mergeSort(numbers, 0, numbers.length4 - 1);68 System.out.println();69 System.out.println("Final: " + Arrays.toString(numbers));70}outputMerged: [1, 2, 3, 4] Final: [1, 2, 3, 4]
public static void main(String[] args)
61}62public static void main(String[] args) {63 int[] numbers = {9, 7, 5, 3, 1};6465 System.out.println("Initial: " + Arrays.toString(numbers));66 System.out.println();67 mergeSort(numbers, 0, numbers.length5 - 1);68 System.out.println();outputInitial: [9, 7, 5, 3, 1]public static void mergeSort(int[] arr, int left, int right)
pass 1 of 95private static int depth = 0;6public static void mergeSort(int[] arr, int left0, int right4) {7 if (left < right) {All 9 passes — pass 1 is the card above pass leftrightmid1 0 4 — 2 0 2 — 3 0 1 — 4 0 0 0 5 1 1 0 6 2 2 1 7 3 4 — 8 3 3 3 9 4 4 3 if (left < right)
pass 1 of 46public static void mergeSort(int[] arr, int left, int right) {7 if (left0 < right4) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left, right));All 4 passes — pass 1 is the card above pass leftright1 0 4 2 0 2 3 0 1 4 3 4 private static void indent()
pass 1 of 127 if (left < right) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left0, right4));10 depth++;1112 int mid = left + (right - left) / 2;1314 mergeSort(arr, left, mid);15 mergeSort(arr, mid + 1, right);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i = 0; i < depth; i++) System.out.print(" ");All 12 passes — pass 1 is the card above pass leftright1 0 4 2 — — 3 — — 4 — — 5 — — 6 — — 7 — — 8 — — 9 — — 10 — — 11 — — 12 0 4 private static String arrayRange(int[] arr, int left, int right)
pass 1 of 856private static String arrayRange(int[] arr, int left0, int right4) {57 int[] range = new int[right4 - left0 + 1];58 for (int i = 0; i < range.length; i++)All 8 passes — pass 1 is the card above pass leftright1 0 4 2 0 2 3 0 1 4 0 1 5 0 2 6 3 4 7 3 4 8 0 4 range[i] ← 9
pass 1 of 2457int[] range = new int[right - left + 1];58for (int i0 = 0; i < range.length5; i++)59 range[i]→ 9 = arr[left + i]9;60return Arrays.toString(range);24 passes — pass 1 is the card above pass irange.lengtharr[left + i]leftrange[i]1 0 5 9 0 0 → 9 2 1 5 7 0 0 → 7 3 2 5 5 0 0 → 5 4 3 5 3 0 0 → 3 5 4 5 1 0 0 → 1 6 0 3 9 0 0 → 9 7 1 3 7 0 0 → 7 8 2 3 5 0 0 → 5 9 0 2 9 0 0 → 9 ⋯ 13 more passes ⋯ 23 3 5 7 0 0 → 7 24 4 5 9 0 0 → 9 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 1, mid ← 2
8indent();9System.out.println("Divide: " + arrayRange(arr, left0, right4));10depth→ 1++;1112int mid→ 2 = left0 + (right4 - left) / 2;1314mergeSort(arr, left0, mid2);15mergeSort(arr, mid + 1, right);outputDivide: [9, 7, 5, 3, 1]for (int i = 0; i < depth; i++)
pass 1 of 167 if (left < right) {8 indent();9 System.out.println("Divide: " + arrayRange(arr, left0, right2));10 depth++;1112 int mid = left + (right - left) / 2;1314 mergeSort(arr, left, mid);15 mergeSort(arr, mid + 1, right);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i0 = 0; i < depth1; i++) System.out.print(" ");54}output16 passes — pass 1 is the card above pass idepthleftrightk1 0 1 0 2 — 2 0 2 — — — 3 1 2 0 1 — 4 0 3 — — — 5 1 3 — — — 6 2 3 — — 0 7 0 2 — — — 8 1 2 0 1 — 9 0 2 — — — ⋯ 5 more passes ⋯ 15 0 1 3 4 — 16 0 1 — — 0 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 2, mid ← 1
8indent();9System.out.println("Divide: " + arrayRange(arr, left0, right2));10depth→ 2++;1112int mid→ 1 = left0 + (right2 - left) / 2;1314mergeSort(arr, left0, mid1);15mergeSort(arr, mid + 1, right);outputDivide: [9, 7, 5]return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 3, mid ← 0
8indent();9System.out.println("Divide: " + arrayRange(arr, left0, right1));10depth→ 3++;1112int mid→ 0 = left0 + (right1 - left) / 2;1314mergeSort(arr, left0, mid0);15mergeSort(arr, mid + 1, right);outputDivide: [9, 7]n1 ← 1, n2 ← 1
pass 1 of 423}24public static void merge(int[] arr, int left0, int mid0, int right1) {25 int n1→ 1 = mid0 - left0 + 1;26 int n2→ 1 = right1 - mid0;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];All 4 passes — pass 1 is the card above pass leftmidrightn1n21 0 0 1 1 1 2 0 1 2 2 1 3 3 3 4 1 1 4 0 2 4 3 2 leftArr[i] ← 9
pass 1 of 730for (int i0 = 0; i < n11; i++)31 leftArr[i]→ 9 = arr[left + i]9;32for (int j = 0; j < n2; j++)All 7 passes — pass 1 is the card above pass in1arr[left + i]leftleftArr[i]1 0 1 9 0 0 → 9 2 0 2 7 0 0 → 7 3 1 2 9 0 0 → 9 4 0 1 3 3 0 → 3 5 0 3 5 0 0 → 5 6 1 3 7 0 0 → 7 7 2 3 9 0 0 → 9 rightArr[j] ← 7
pass 1 of 531 leftArr[i] = arr[left + i];32for (int j0 = 0; j < n21; j++)33 rightArr[j]→ 7 = arr[mid + 1 + j]7;All 5 passes — pass 1 is the card above pass jn2arr[mid + 1 + j]midrightArr[j]1 0 1 7 0 0 → 7 2 0 1 5 1 0 → 5 3 0 1 1 3 0 → 1 4 0 2 1 2 0 → 1 5 1 2 3 2 0 → 3 indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +while (i < n1 && j < n2)
pass 1 of 539int i = 0, j = 0, k = left;40while (i0 < n11 && j0 < n21) {41 if (leftArr[i] <= rightArr[j]) {All 5 passes — pass 1 is the card above pass n1jn21 1 0 1 2 2 0 1 3 1 0 1 4 3 0 2 5 3 1 2 k ← 1, j ← 1
pass 1 of 542 arr[k++] = leftArr[i++];43} else {44 arr[k→ 1++] = rightArr[j→ 1++];45}All 5 passes — pass 1 is the card above pass kj1 0 → 1 0 → 1 2 0 → 1 0 → 1 3 3 → 4 0 → 1 4 0 → 1 0 → 1 5 1 → 2 1 → 2 k ← 2, i ← 1, depth ← 2
pass 1 of 717 merge(arr, left0, mid0, right1);1819 depth→ 2--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left, right));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i0 < n11) arr[k→ 2++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];All 7 passes — pass 1 is the card above pass n1leftmidrightkidepth1 1 0 0 1 1 → 2 0 → 1 3 → 2 2 2 — — — 1 → 2 0 → 1 — 3 2 0 1 2 2 → 3 1 → 2 2 → 1 4 1 3 3 4 4 → 5 0 → 1 2 → 1 5 3 — — — 2 → 3 0 → 1 — 6 3 — — — 3 → 4 1 → 2 — 7 3 0 2 4 4 → 5 2 → 3 1 → 0 return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}left ← 0, mid ← 1
14 mergeSort(arr, left→ 0, mid→ 1);15 mergeSort(arr, mid1 + 1, right2);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left0, right1));22}outputMerged: [7, 9]indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}left ← 0, mid ← 2
14 mergeSort(arr, left→ 0, mid→ 2);15 mergeSort(arr, mid2 + 1, right4);1617 merge(arr, left, mid, right);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left0, right2));22}outputMerged: [5, 7, 9]return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}depth ← 2, mid ← 3
8indent();9System.out.println("Divide: " + arrayRange(arr, left3, right4));10depth→ 2++;1112int mid→ 3 = left3 + (right4 - left) / 2;1314mergeSort(arr, left3, mid3);15mergeSort(arr, mid + 1, right);outputDivide: [3, 1]indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}mid ← 2, right ← 4
14 mergeSort(arr, left, mid);15 mergeSort(arr, mid→ 2 + 1, right→ 4);1617 merge(arr, left0, mid2, right4);1819 depth--;20 indent();21 System.out.println("Merged: " + arrayRange(arr, left3, right4));22}outputMerged: [1, 3]indent();
35indent();36System.out.println(" Merge " + Arrays.toString(leftArr) +return Arrays.toString(range);
59 range[i] = arr[left + i];60 return Arrays.toString(range);61}System.out.println("Merged: " + arrayRange(arr, left, right));
20 indent();21 System.out.println("Merged: " + arrayRange(arr, left0, right4));22 }23}24public static void merge(int[] arr, int left, int mid, int right) {25 int n1 = mid - left + 1;26 int n2 = right - mid;27 int[] leftArr = new int[n1];28 int[] rightArr = new int[n2];2930 for (int i = 0; i < n1; i++)31 leftArr[i] = arr[left + i];32 for (int j = 0; j < n2; j++)33 rightArr[j] = arr[mid + 1 + j];3435 indent();36 System.out.println(" Merge " + Arrays.toString(leftArr) + 37 " and " + Arrays.toString(rightArr));3839 int i = 0, j = 0, k = left;40 while (i < n1 && j < n2) {41 if (leftArr[i] <= rightArr[j]) {42 arr[k++] = leftArr[i++];43 } else {44 arr[k++] = rightArr[j++];45 }46 }4748 while (i < n1) arr[k++] = leftArr[i++];49 while (j < n2) arr[k++] = rightArr[j++];50}5152private static void indent() {53 for (int i = 0; i < depth; i++) System.out.print(" ");54}5556private static String arrayRange(int[] arr, int left, int right) {57 int[] range = new int[right - left + 1];58 for (int i = 0; i < range.length; i++)59 range[i] = arr[left + i];60 return Arrays.toString(range);61}62public static void main(String[] args) {63 int[] numbers = {9, 7, 5, 3, 1};6465 System.out.println("Initial: " + Arrays.toString(numbers));66 System.out.println();67 mergeSort(numbers, 0, numbers.length5 - 1);68 System.out.println();69 System.out.println("Final: " + Arrays.toString(numbers));70}outputMerged: [1, 3, 5, 7, 9] Final: [1, 3, 5, 7, 9]
The Merge Operation
MergeOnly.java
Replay: real traced execution (multi-file project)
import java.util.Arrays;
public class MergeOnly {
public static int[] mergeTwoSorted(int[] left, int[] right) {
int[] result = new int[left.length + right.length];
int i = 0, j = 0, k = 0;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
result[k++] = left[i++];
} else {
result[k++] = right[j++];
}
}
while (i < left.length) {
result[k++] = left[i++];
}
while (j < right.length) {
result[k++] = right[j++];
}
return result;
}
public static void main(String[] args) {
int[] left = {1, 3, 5, 7};
int[] right = {2, 4, 6, 8};
System.out.println("Left: " + Arrays.toString(left));
System.out.println("Right: " + Arrays.toString(right));
int[] merged = mergeTwoSorted(left, right);
System.out.println("Merged: " + Arrays.toString(merged));
int[] arr1 = {1, 5, 9};
int[] arr2 = {2, 3, 4, 6, 7};
System.out.println("\nLeft: " + Arrays.toString(arr1));
System.out.println("Right: " + Arrays.toString(arr2));
int[] merged2 = mergeTwoSorted(arr1, arr2);
System.out.println("Merged: " + Arrays.toString(merged2));
}
}
public static void main(String[] args)
22}23public static void main(String[] args) {24 int[] left = {1, 3, 5, 7};25 int[] right = {2, 4, 6, 8};2627 System.out.println("Left: " + Arrays.toString(left));28 System.out.println("Right: " + Arrays.toString(right));2930 int[] merged = mergeTwoSorted(left, right);31 System.out.println("Merged: " + Arrays.toString(merged));outputLeft: [1, 3, 5, 7] Right: [2, 4, 6, 8]k ← 0
pass 1 of 23public class MergeOnly {4 public static int[] mergeTwoSorted(int[] left, int[] right) {5 int[] result = new int[left.length4 + right.length4];6 int i = 0, j = 0, k→ 0 = 0;7 while (i < left.length && j < right.length) {while (i < left.length && j < right.length)
pass 1 of 146int i = 0, j = 0, k = 0;7while (i0 < left.length4 && j0 < right.length4) {8 if (left[i] <= right[j]) {14 passes — pass 1 is the card above pass left.lengthright.lengthkji1 4 4 — 0 0 2 4 4 — 0 1 3 4 4 — 1 1 4 4 4 — 1 2 5 4 4 — 2 2 6 4 4 — 2 3 7 4 4 7 → 8 3 → 4 3 8 3 5 — 0 0 9 3 5 — 0 1 ⋯ 3 more passes ⋯ 13 3 5 — 3 2 14 3 5 7 → 8 4 2 → 3 k ← 1, i ← 1
pass 1 of 67while (i < left.length && j < right.length) {8 if (left[i]1 <= right[j]2) {9 result[k→ 1++] = left[i→ 1++];10 } else {All 6 passes — pass 1 is the card above pass left[i]right[j]right.lengthleft.lengthkij1 1 2 — — 0 → 1 0 → 1 0 2 3 4 — — 2 → 3 1 → 2 1 3 5 6 — — 4 → 5 2 → 3 2 4 7 8 4 — 6 → 7 3 → 4 3 → 4 5 1 2 — — 0 → 1 0 → 1 0 6 5 6 — 3 4 → 5 1 → 2 3 k ← 2, j ← 1
pass 1 of 89 result[k++] = left[i++];10} else {11 result[k→ 2++] = right[j→ 1++];12}All 8 passes — pass 1 is the card above pass right.lengthleft.lengthkji1 — — 1 → 2 0 → 1 — 2 — — 3 → 4 1 → 2 — 3 4 — 5 → 6 2 → 3 — 4 — — 1 → 2 0 → 1 — 5 — — 2 → 3 1 → 2 — 6 — — 3 → 4 2 → 3 — 7 — — 5 → 6 3 → 4 — 8 — 3 6 → 7 4 → 5 2 → 3 k ← 8, j ← 4
16}17while (j3 < right.length4) {18 result[k→ 8++] = right[j→ 4++];19}return result;
21 return result;22}int[] merged = mergeTwoSorted(left, right);
30int[] merged = mergeTwoSorted(left, right);31System.out.println("Merged: " + Arrays.toString(merged));32int[] arr1 = {1, 5, 9};33int[] arr2 = {2, 3, 4, 6, 7};3435System.out.println("\nLeft: " + Arrays.toString(arr1));36System.out.println("Right: " + Arrays.toString(arr2));3738int[] merged2 = mergeTwoSorted(arr1, arr2);39System.out.println("Merged: " + Arrays.toString(merged2));outputMerged: [1, 2, 3, 4, 5, 6, 7, 8] Left: [1, 5, 9] Right: [2, 3, 4, 6, 7]k ← 0
pass 2 of 23public class MergeOnly {4 public static int[] mergeTwoSorted(int[] left, int[] right) {5 int[] result = new int[left.length3 + right.length5];6 int i = 0, j = 0, k→ 0 = 0;7 while (i < left.length && j < right.length) {k ← 8, i ← 3
13}14while (i2 < left.length3) {15 result[k→ 8++] = left[i→ 3++];16}return result;
21 return result;22}int[] merged2 = mergeTwoSorted(arr1, arr2);
38 int[] merged2 = mergeTwoSorted(arr1, arr2);39 System.out.println("Merged: " + Arrays.toString(merged2));40}outputMerged: [1, 2, 3, 4, 5, 6, 7, 9]
Merge Operation
The step that combines two sorted arrays into one sorted array by comparing the front values of each input.
Iterative Version
Bottom-up merge sort starts with runs of size one and repeatedly merges larger adjacent runs.
Iterative.java
Replay: real traced execution (multi-file project)
import java.util.Arrays;
public class Iterative {
public static void mergeSortIterative(int[] arr) {
int n = arr.length;
for (int size = 1; size < n; size = size * 2) {
for (int left = 0; left < n - 1; left += size * 2) {
int mid = Math.min(left + size - 1, n - 1);
int right = Math.min(left + size * 2 - 1, n - 1);
merge(arr, left, mid, right);
}
}
}
public static void merge(int[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
int[] leftArr = new int[n1];
int[] rightArr = new int[n2];
for (int i = 0; i < n1; i++)
leftArr[i] = arr[left + i];
for (int j = 0; j < n2; j++)
rightArr[j] = arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i] <= rightArr[j]) {
arr[k++] = leftArr[i++];
} else {
arr[k++] = rightArr[j++];
}
}
while (i < n1) arr[k++] = leftArr[i++];
while (j < n2) arr[k++] = rightArr[j++];
}
public static void main(String[] args) {
int[] numbers = {38, 27, 43, 3, 9, 82, 10};
System.out.println("Before: " + Arrays.toString(numbers));
mergeSortIterative(numbers);
System.out.println("After: " + Arrays.toString(numbers));
}
}
public static void main(String[] args)
37}38public static void main(String[] args) {39 int[] numbers = {38, 27, 43, 3, 9, 82, 10};4041 System.out.println("Before: " + Arrays.toString(numbers));42 mergeSortIterative(numbers);43 System.out.println("After: " + Arrays.toString(numbers));outputBefore: [38, 27, 43, 3, 9, 82, 10]n ← 7
3public class Iterative {4 public static void mergeSortIterative(int[] arr) {5 int n→ 7 = arr.length7;6 for (int size = 1; size < n; size = size * 2) {for (int size = 1; size < n; size = size * 2)
pass 1 of 35int n = arr.length;6for (int size1 = 1; size < n7; size = size * 2) {7 for (int left = 0; left < n - 1; left += size * 2) {All 3 passes — pass 1 is the card above pass size1 1 2 2 3 4 mid ← 0, right ← 1
pass 1 of 66for (int size = 1; size < n; size = size * 2) {7 for (int left0 = 0; left < n7 - 1; left += size1 * 2) {8 int mid→ 0 = Math.min(left0 + size1 - 1, n7 - 1);9 int right→ 1 = Math.min(left0 + size1 * 2 - 1, n7 - 1);1011 merge(arr, left0, mid0, right1);12 }All 6 passes — pass 1 is the card above pass leftsizemidright1 0 1 0 1 2 2 1 2 3 3 4 1 4 5 4 0 2 1 3 5 4 2 5 6 6 0 4 3 6 n1 ← 1, n2 ← 1
pass 1 of 614}15public static void merge(int[] arr, int left0, int mid0, int right1) {16 int n1→ 1 = mid0 - left0 + 1;17 int n2→ 1 = right1 - mid0;18 int[] leftArr = new int[n1];19 int[] rightArr = new int[n2];All 6 passes — pass 1 is the card above pass leftmidrightn1n21 0 0 1 1 1 2 2 2 3 1 1 3 4 4 5 1 1 4 0 1 3 2 2 5 4 5 6 2 1 6 0 3 6 4 3 leftArr[i] ← 38
pass 1 of 1121for (int i0 = 0; i < n11; i++)22 leftArr[i]→ 38 = arr[left + i]38;23for (int j = 0; j < n2; j++)All 11 passes — pass 1 is the card above pass in1arr[left + i]leftleftArr[i]1 0 1 38 0 0 → 38 2 0 1 43 2 0 → 43 3 0 1 9 4 0 → 9 4 0 2 27 0 0 → 27 5 1 2 38 0 0 → 38 6 0 2 9 4 0 → 9 7 1 2 82 4 0 → 82 8 0 4 3 0 0 → 3 9 1 4 27 0 0 → 27 10 2 4 38 0 0 → 38 11 3 4 43 0 0 → 43 rightArr[j] ← 27
pass 1 of 922 leftArr[i] = arr[left + i];23for (int j0 = 0; j < n21; j++)24 rightArr[j]→ 27 = arr[mid + 1 + j]27;All 9 passes — pass 1 is the card above pass jn2arr[mid + 1 + j]midrightArr[j]1 0 1 27 0 0 → 27 2 0 1 3 2 0 → 3 3 0 1 82 4 0 → 82 4 0 2 3 1 0 → 3 5 1 2 43 1 0 → 43 6 0 1 10 5 0 → 10 7 0 3 9 3 0 → 9 8 1 3 10 3 0 → 10 9 2 3 82 3 0 → 82 k ← 0
26int i = 0, j = 0, k→ 0 = left;27while (i < n1 && j < n2) {while (i < n1 && j < n2)
pass 1 of 1426int i = 0, j = 0, k = left;27while (i0 < n11 && j0 < n21) {28 if (leftArr[i] <= rightArr[j]) {14 passes — pass 1 is the card above pass in1jn21 0 1 0 1 2 0 1 0 1 3 0 1 0 1 4 0 2 0 2 5 0 2 1 2 6 1 2 1 2 7 0 2 0 1 8 1 2 0 1 9 0 4 0 3 ⋯ 3 more passes ⋯ 13 2 4 2 3 14 3 4 2 3 k ← 1, j ← 1
pass 1 of 629 arr[k++] = leftArr[i++];30} else {31 arr[k→ 1++] = rightArr[j→ 1++];32}All 6 passes — pass 1 is the card above pass kj1 0 → 1 0 → 1 2 2 → 3 0 → 1 3 0 → 1 0 → 1 4 5 → 6 0 → 1 5 1 → 2 0 → 1 6 2 → 3 1 → 2 k ← 2, i ← 1
pass 1 of 311 merge(arr, left0, mid0, right1);12 }13 }14}15public static void merge(int[] arr, int left, int mid, int right) {16 int n1 = mid - left + 1;17 int n2 = right - mid;18 int[] leftArr = new int[n1];19 int[] rightArr = new int[n2];2021 for (int i = 0; i < n1; i++)22 leftArr[i] = arr[left + i];23 for (int j = 0; j < n2; j++)24 rightArr[j] = arr[mid + 1 + j];2526 int i = 0, j = 0, k = left;27 while (i < n1 && j < n2) {28 if (leftArr[i] <= rightArr[j]) {29 arr[k++] = leftArr[i++];30 } else {31 arr[k++] = rightArr[j++];32 }33 }3435 while (i0 < n11) arr[k→ 2++] = leftArr[i++];36 while (j < n2) arr[k++] = rightArr[j++];All 3 passes — pass 1 is the card above pass n1leftmidrightki1 1 0 0 1 1 → 2 0 → 1 2 1 2 2 3 3 → 4 0 → 1 3 2 4 5 6 6 → 7 1 → 2 k ← 2
26int i = 0, j = 0, k→ 2 = left;27while (i < n1 && j < n2) {k ← 4
26int i = 0, j = 0, k→ 4 = left;27while (i < n1 && j < n2) {k ← 5, i ← 1
pass 1 of 827while (i < n1 && j < n2) {28 if (leftArr[i]9 <= rightArr[j]82) {29 arr[k→ 5++] = leftArr[i→ 1++];30 } else {All 8 passes — pass 1 is the card above pass leftArr[i]rightArr[j]jki1 9 82 0 4 → 5 0 → 1 2 27 43 1 1 → 2 0 → 1 3 38 43 1 2 → 3 1 → 2 4 9 10 0 4 → 5 0 → 1 5 3 9 0 0 → 1 0 → 1 6 27 82 2 3 → 4 1 → 2 7 38 82 2 4 → 5 2 → 3 8 43 82 2 5 → 6 3 → 4 k ← 6, j ← 1
pass 1 of 311 merge(arr, left4, mid4, right5);12 }13 }14}15public static void merge(int[] arr, int left, int mid, int right) {16 int n1 = mid - left + 1;17 int n2 = right - mid;18 int[] leftArr = new int[n1];19 int[] rightArr = new int[n2];2021 for (int i = 0; i < n1; i++)22 leftArr[i] = arr[left + i];23 for (int j = 0; j < n2; j++)24 rightArr[j] = arr[mid + 1 + j];2526 int i = 0, j = 0, k = left;27 while (i < n1 && j < n2) {28 if (leftArr[i] <= rightArr[j]) {29 arr[k++] = leftArr[i++];30 } else {31 arr[k++] = rightArr[j++];32 }33 }3435 while (i < n1) arr[k++] = leftArr[i++];36 while (j0 < n21) arr[k→ 6++] = rightArr[j++];37}All 3 passes — pass 1 is the card above pass n2leftmidrightkj1 1 4 4 5 5 → 6 0 → 1 2 2 0 1 3 3 → 4 1 → 2 3 3 0 3 6 6 → 7 2 → 3 k ← 0
26int i = 0, j = 0, k→ 0 = left;27while (i < n1 && j < n2) {k ← 4
26int i = 0, j = 0, k→ 4 = left;27while (i < n1 && j < n2) {k ← 0
26int i = 0, j = 0, k→ 0 = left;27while (i < n1 && j < n2) {mergeSortIterative(numbers);
41 System.out.println("Before: " + Arrays.toString(numbers));42 mergeSortIterative(numbers);43 System.out.println("After: " + Arrays.toString(numbers));44}outputAfter: [3, 9, 10, 27, 38, 43, 82]
Practical Use
Merge sort is useful when stable, predictable sorting matters.
Practical.java
Replay: real traced execution (multi-file project)
import java.util.Arrays;
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
public String toString() {
return name + ":" + score;
}
}
public class Practical {
public static void mergeSort(Student[] arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
public static void merge(Student[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
Student[] leftArr = new Student[n1];
Student[] rightArr = new Student[n2];
for (int i = 0; i < n1; i++)
leftArr[i] = arr[left + i];
for (int j = 0; j < n2; j++)
rightArr[j] = arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i].score >= rightArr[j].score) {
arr[k++] = leftArr[i++];
} else {
arr[k++] = rightArr[j++];
}
}
while (i < n1) arr[k++] = leftArr[i++];
while (j < n2) arr[k++] = rightArr[j++];
}
public static void main(String[] args) {
Student[] students = {
new Student("Alice", 85),
new Student("Bob", 92),
new Student("Charlie", 78),
new Student("Diana", 95),
new Student("Eve", 88)
};
System.out.println("Before: " + Arrays.toString(students));
mergeSort(students, 0, students.length - 1);
System.out.println("After: " + Arrays.toString(students));
System.out.println("\nTop 3 students:");
for (int i = 0; i < 3 && i < students.length; i++) {
System.out.println((i + 1) + ". " + students[i]);
}
}
}
public static void main(String[] args)
48}49public static void main(String[] args) {50 Student[] students = {51 new Student("Alice", 85),52 new Student("Bob", 92),53 new Student("Charlie", 78),54 new Student("Diana", 95),55 new Student("Eve", 88)56 };this.name ← Alice, this.score ← 85
pass 1 of 57Student(String nameAlice, int score85) {8 this.name→ Alice = nameAlice;9 this.score→ 85 = score85;10}All 5 passes — pass 1 is the card above pass namescorethis.namethis.score1 Alice 85 Alice 85 2 Bob 92 Bob 92 3 Charlie 78 Charlie 78 4 Diana 95 Diana 95 5 Eve 88 Eve 88 Student[] students =
49public static void main(String[] args) {50 Student[] students = {51 new Student("Alice", 85),52 new Student("Bob", 92),53 new Student("Charlie", 78),54 new Student("Diana", 95),55 new Student("Eve", 88)56 };5758 System.out.println("Before: " + Arrays.toString(students));59 mergeSort(students, 0, students.length5 - 1);60 System.out.println("After: " + Arrays.toString(students));outputBefore: [Alice:85, Bob:92, Charlie:78, Diana:95, Eve:88]public static void mergeSort(Student[] arr, int left, int right)
pass 1 of 917public class Practical {18 public static void mergeSort(Student[] arr, int left0, int right4) {19 if (left < right) {All 9 passes — pass 1 is the card above pass leftrightmid1 0 4 — 2 0 2 — 3 0 1 — 4 0 0 0 5 1 1 0 6 2 2 1 7 3 4 — 8 3 3 3 9 4 4 3 mid ← 2
pass 1 of 418public static void mergeSort(Student[] arr, int left, int right) {19 if (left0 < right4) {20 int mid→ 2 = left0 + (right4 - left) / 2;21 mergeSort(arr, left0, mid2);22 mergeSort(arr, mid + 1, right);All 4 passes — pass 1 is the card above pass leftrightmid1 0 4 2 2 0 2 1 3 0 1 0 4 3 4 3 n1 ← 1, n2 ← 1
pass 1 of 425}26public static void merge(Student[] arr, int left0, int mid0, int right1) {27 int n1→ 1 = mid0 - left0 + 1;28 int n2→ 1 = right1 - mid0;29 Student[] leftArr = new Student[n1];30 Student[] rightArr = new Student[n2];All 4 passes — pass 1 is the card above pass leftmidrightn1n21 0 0 1 1 1 2 0 1 2 2 1 3 3 3 4 1 1 4 0 2 4 3 2 leftArr[i] ← Alice:85
pass 1 of 732for (int i0 = 0; i < n11; i++)33 leftArr[i]→ Alice:85 = arr[left + i]Alice:85;34for (int j = 0; j < n2; j++)All 7 passes — pass 1 is the card above pass in1arr[left + i]leftleftArr[i]1 0 1 Alice:85 0 null → Alice:85 2 0 2 Bob:92 0 null → Bob:92 3 1 2 Alice:85 0 null → Alice:85 4 0 1 Diana:95 3 null → Diana:95 5 0 3 Bob:92 0 null → Bob:92 6 1 3 Alice:85 0 null → Alice:85 7 2 3 Charlie:78 0 null → Charlie:78 rightArr[j] ← Bob:92
pass 1 of 533 leftArr[i] = arr[left + i];34for (int j0 = 0; j < n21; j++)35 rightArr[j]→ Bob:92 = arr[mid + 1 + j]Bob:92;All 5 passes — pass 1 is the card above pass jn2arr[mid + 1 + j]midrightArr[j]1 0 1 Bob:92 0 null → Bob:92 2 0 1 Charlie:78 1 null → Charlie:78 3 0 1 Eve:88 3 null → Eve:88 4 0 2 Diana:95 2 null → Diana:95 5 1 2 Eve:88 2 null → Eve:88 k ← 0
37int i = 0, j = 0, k→ 0 = left;38while (i < n1 && j < n2) {while (i < n1 && j < n2)
pass 1 of 737int i = 0, j = 0, k = left;38while (i0 < n11 && j0 < n21) {39 if (leftArr[i].score >= rightArr[j].score) {All 7 passes — pass 1 is the card above pass in1n2kjleftmidright1 0 1 1 — 0 — — — 2 0 2 1 — 0 — — — 3 1 2 1 2 → 3 0 → 1 0 1 → 2 2 4 0 1 1 4 → 5 0 → 1 0 2 4 5 0 3 2 — 0 — — — 6 0 3 2 — 1 — — — 7 1 3 2 — 1 — — — k ← 1, j ← 1
pass 1 of 340 arr[k++] = leftArr[i++];41} else {42 arr[k→ 1++] = rightArr[j→ 1++];43}All 3 passes — pass 1 is the card above pass kj1 0 → 1 0 → 1 2 0 → 1 0 → 1 3 2 → 3 1 → 2 k ← 2, i ← 1, left ← 0, mid ← 1
pass 1 of 320 int mid = left + (right - left) / 2;21 mergeSort(arr, left→ 0, mid→ 1);22 mergeSort(arr, mid1 + 1, right2);23 merge(arr, left0, mid0, right1);24 }25}26public static void merge(Student[] arr, int left, int mid, int right) {27 int n1 = mid - left + 1;28 int n2 = right - mid;29 Student[] leftArr = new Student[n1];30 Student[] rightArr = new Student[n2];3132 for (int i = 0; i < n1; i++)33 leftArr[i] = arr[left + i];34 for (int j = 0; j < n2; j++)35 rightArr[j] = arr[mid + 1 + j];3637 int i = 0, j = 0, k = left;38 while (i < n1 && j < n2) {39 if (leftArr[i].score >= rightArr[j].score) {40 arr[k++] = leftArr[i++];41 } else {42 arr[k++] = rightArr[j++];43 }44 }4546 while (i0 < n11) arr[k→ 2++] = leftArr[i++];47 while (j < n2) arr[k++] = rightArr[j++];All 3 passes — pass 1 is the card above pass n1rightkileftmid1 1 1 1 → 2 0 → 1 0 0 → 1 2 3 — 3 → 4 1 → 2 — — 3 3 4 4 → 5 2 → 3 0 2 k ← 0
37int i = 0, j = 0, k→ 0 = left;38while (i < n1 && j < n2) {k ← 1, i ← 1
pass 1 of 438while (i < n1 && j < n2) {39 if (leftArr[i].score92 >= rightArr[j].score78) {40 arr[k→ 1++] = leftArr[i→ 1++];41 } else {All 4 passes — pass 1 is the card above pass leftArr[i].scoreleftArr[i]rightArr[j].scorerightArr[j]n2kijleftmidright1 92 Bob:92 78 Charlie:78 — 0 → 1 0 → 1 0 — — — 2 85 Alice:85 78 Charlie:78 1 1 → 2 1 → 2 0 → 1 0 1 → 2 2 3 95 Diana:95 88 Eve:88 1 3 → 4 0 → 1 0 → 1 0 2 4 4 92 Bob:92 88 Eve:88 — 1 → 2 0 → 1 1 — — — k ← 3, j ← 1, left ← 0, mid ← 2
pass 1 of 220 int mid = left + (right - left) / 2;21 mergeSort(arr, left→ 0, mid→ 2);22 mergeSort(arr, mid2 + 1, right4);23 merge(arr, left0, mid1, right2);24 }25}26public static void merge(Student[] arr, int left, int mid, int right) {27 int n1 = mid - left + 1;28 int n2 = right - mid;29 Student[] leftArr = new Student[n1];30 Student[] rightArr = new Student[n2];3132 for (int i = 0; i < n1; i++)33 leftArr[i] = arr[left + i];34 for (int j = 0; j < n2; j++)35 rightArr[j] = arr[mid + 1 + j];3637 int i = 0, j = 0, k = left;38 while (i < n1 && j < n2) {39 if (leftArr[i].score >= rightArr[j].score) {40 arr[k++] = leftArr[i++];41 } else {42 arr[k++] = rightArr[j++];43 }44 }4546 while (i < n1) arr[k++] = leftArr[i++];47 while (j0 < n21) arr[k→ 3++] = rightArr[j++];48}k ← 3
37int i = 0, j = 0, k→ 3 = left;38while (i < n1 && j < n2) {k ← 5, j ← 1, mid ← 2, right ← 4
pass 2 of 221 mergeSort(arr, left, mid);22 mergeSort(arr, mid→ 2 + 1, right→ 4);23 merge(arr, left0, mid2, right4);24 }25}26public static void merge(Student[] arr, int left, int mid, int right) {27 int n1 = mid - left + 1;28 int n2 = right - mid;29 Student[] leftArr = new Student[n1];30 Student[] rightArr = new Student[n2];3132 for (int i = 0; i < n1; i++)33 leftArr[i] = arr[left + i];34 for (int j = 0; j < n2; j++)35 rightArr[j] = arr[mid + 1 + j];3637 int i = 0, j = 0, k = left;38 while (i < n1 && j < n2) {39 if (leftArr[i].score >= rightArr[j].score) {40 arr[k++] = leftArr[i++];41 } else {42 arr[k++] = rightArr[j++];43 }44 }4546 while (i < n1) arr[k++] = leftArr[i++];47 while (j0 < n21) arr[k→ 5++] = rightArr[j++];48}k ← 0
37int i = 0, j = 0, k→ 0 = left;38while (i < n1 && j < n2) {mergeSort(students, 0, students.length - 1);
58System.out.println("Before: " + Arrays.toString(students));59mergeSort(students, 0, students.length5 - 1);60System.out.println("After: " + Arrays.toString(students));6162System.out.println("\nTop 3 students:");63for (int i = 0; i < 3 && i < students.length; i++) {outputAfter: [Diana:95, Bob:92, Eve:88, Alice:85, Charlie:78] Top 3 students:for (int i = 0; i < 3 && i < students.length; i++)
pass 1 of 362System.out.println("\nTop 3 students:");63for (int i0 = 0; i < 3 && i < students.length5; i++) {64 System.out.println((i0 + 1) + ". " + students[i]Diana:95);65}output1. Diana:95All 3 passes — pass 1 is the card above pass istudents[i]1 0 Diana:95 2 1 Bob:92 3 2 Eve:88
Exercise: Practical.java
Implement a merge function that counts the number of inversions while merging