Merge Sort
Definition​
- Definition
- Explanation
- Guidance
- Tips
Merge Sort is a popular comparison-based sorting algorithm that follows the divide-and-conquer paradigm. It recursively divides the input array into smaller sub-arrays until each sub-array contains only one element, then merges those sub-arrays in a sorted manner
Merge Sort operates by dividing the array into halves until each subset contains only one element. Then, it merges adjacent pairs of these subsets, comparing elements and arranging them in the correct order. This process continues recursively until the entire array is sorted. The key operation is the merging step, where two sorted arrays are combined into a single sorted array. It repeatedly compares the elements from the two arrays, selecting the smaller (or larger) element and appending it to the result array until one of the arrays is exhausted. The remaining elements from the non-empty array are then appended to the result
- Divide the array into two halves
- Recursively apply Merge Sort on each half until each sub-array contains only one element
- Merge the sorted sub-arrays by comparing elements from each and arranging them in ascending order
- repeat until all sub-arrays are merged into a single sorted array
- ensure proper handling of edge cases, such as empty arrays or arrays with only one element
- use an auxiliary array during the merging step to store the sorted elements temporarily
- consider implementing an optimized version of Merge Sort that avoids unnecessary memory allocations or copying of arrays
Practice​
- Practice
- Solution
mergeSort(array)
if length of array <= 1
return array
else
mid = length of array / 2
leftArray = mergeSort(first half of array)
rightArray = mergeSort(second half of array)
return merge(leftArray, rightArray)
merge(leftArray, rightArray)
result = []
while leftArray is not empty and rightArray is not empty
if first element of leftArray <= first element of rightArray
append first element of leftArray to result
remove first element from leftArray
else
append first element of rightArray to result
remove first element from rightArray
append remaining elements of leftArray to result
append remaining elements of rightArray to result
return result
package main
func mergeSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}
mid := len(arr) / 2
left := mergeSort(arr[:mid])
right := mergeSort(arr[mid:])
return merge(left, right)
}
func merge(left, right []int) []int {
result := make([]int, 0, len(left)+len(right))
for len(left) > 0 || len(right) > 0 {
if len(left) == 0 {
return append(result, right...)
}
if len(right) == 0 {
return append(result, left...)
}
if left[0] <= right[0] {
result = append(result, left[0])
left = left[1:]
} else {
result = append(result, right[0])
right = right[1:]
}
}
return result
}
import java.util.Arrays;
public class MergeSort {
public static void mergeSort(int[] arr) {
if (arr.length <= 1) {
return;
}
int mid = arr.length / 2;
int[] left = Arrays.copyOfRange(arr, 0, mid);
int[] right = Arrays.copyOfRange(arr, mid, arr.length);
mergeSort(left);
mergeSort(right);
merge(arr, left, right);
}
public static void merge(int[] arr, int[] left, int[] right) {
int i = 0, j = 0, k = 0;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
while (i < left.length) {
arr[k++] = left[i++];
}
while (j < right.length) {
arr[k++] = right[j++];
}
}
}
function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left, right) {
let result = [];
let leftIndex = 0;
let rightIndex = 0;
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex]);
leftIndex++;
} else {
result.push(right[rightIndex]);
rightIndex++;
}
}
return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}
fun mergeSort(arr: IntArray): IntArray {
if (arr.size <= 1) return arr
val mid = arr.size / 2
val left = mergeSort(arr.sliceArray(0 until mid))
val right = mergeSort(arr.sliceArray(mid until arr.size))
return merge(left, right)
}
fun merge(left: IntArray, right: IntArray): IntArray {
val result = mutableListOf<Int>()
var leftIndex = 0
var rightIndex = 0
while (leftIndex < left.size && rightIndex < right.size) {
if (left[leftIndex] < right[rightIndex]) {
result.add(left[leftIndex])
leftIndex++
} else {
result.add(right[rightIndex])
rightIndex++
}
}
while (leftIndex < left.size) {
result.add(left[leftIndex])
leftIndex++
}
while (rightIndex < right.size) {
result.add(right[rightIndex])
rightIndex++
}
return result.toIntArray()
}
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result.extend(left[i:])
result.extend(right[j:])
return result
fn merge_sort(arr: &mut [i32]) {
if arr.len() <= 1 {
return;
}
let mid = arr.len() / 2;
let (left, right) = arr.split_at_mut(mid);
merge_sort(left);
merge_sort(right);
merge(arr, left, right);
}
fn merge(arr: &mut [i32], left: &mut [i32], right: &mut [i32]) {
let mut i = 0;
let mut j = 0;
let mut k = 0;
while i < left.len() && j < right.len() {
if left[i] <= right[j] {
arr[k] = left[i];
i += 1;
} else {
arr[k] = right[j];
j += 1;
}
k += 1;
}
while i < left.len() {
arr[k] = left[i];
i += 1;
k += 1;
}
while j < right.len() {
arr[k] = right[j];
j += 1;
k += 1;
}
}
function mergeSort(arr: number[]): number[] {
if (arr.length <= 1) {
return arr;
}
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left: number[], right: number[]): number[] {
let result: number[] = [];
let leftIndex = 0;
let rightIndex = 0;
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex]);
leftIndex++;
} else {
result.push(right[rightIndex]);
rightIndex++;
}
}
return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}