Merge sort ideas
1, the elements to be sorted into two
2, for the left and right halves elements were split again, until you can no longer split
3, to split off and combined elements reorder
4, after the merger of the array after the array is the sort of final
Merge sort understanding
Merge sort complete binary tree sorting applied idea of the array are arranged in layers with divided equally divided form as a complete binary tree, then each element of check points starting from the bottom, were pooled up layer by layer, until again and to an ordered array, complete the entire ordering process.
Merge sort Complexity
Since the merge sort using a complete binary tree form, depending on the complexity of the binary tree understood, the time taken for the O (logn), and merge sort is necessary to trip the adjacent elements pairwise merge that all the elements to be sorted to be scanned again, the time complexity is O (n), therefore, the merge sort total time complexity is O (nlogn).
Because of the need to merge sort the same magnitude and the original data storage space to store the result of merging, and a depth of recursion logn space station, and therefore, the merge sort space complexity is O (n + logn).
Merge sort Features
Since the merge sort requires pairwise comparison, comparative embodiment jumping does not exist, merge sort is a stable sorting algorithm.
To sum up, merge sort is a relatively take up memory space, but efficient and stable sorting algorithm.
Merge sort JAVA implementation
Recursive
public static void main(String[] args) {
int[] arr = {2, 56, 2, 13, 54, 23, 1};
mergeSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
private static void merge(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
// p1是左半边指针
int p1 = left;
// p2是右半边指针
int p2 = mid + 1;
// 合并后数组指针
int k = 0;
while (p1 <= mid && p2 <= right) {
if (arr[p1] < arr[p2]) {
temp[k++] = arr[p1++];
} else {
temp[k++] = arr[p2++];
}
}
while (p1 <= mid) {
temp[k++] = arr[p1++];
}
while (p2 <= right) {
temp[k++] = arr[p2++];
}
for (int i = 0; i < temp.length; i++) {
arr[left + i] = temp[i];
}
}
private static void mergeSort(int[] arr, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
mergeSort(arr, start, mid);
mergeSort(arr, mid + 1, end);
merge(arr, start, mid, end);
}
}
}
Non-recursive
public class Main {
public static void main(String[] args) {
int[] arr = {2, 56, 2, 13, 54, 23, 1};
mergeSort(arr);
System.out.println(Arrays.toString(arr));
}
private static void mergeSort(int[] arr) {
// 使用非递归方式实现归并排序
int len = arr.length;
int k = 1;
while (k < len) {
mergePass(arr, k, len);
k *= 2;
}
}
private static void mergePass(int[] arr, int k, int n) {
int i = 0;
// 从前往后走,将2个长度为k的子序列合并为1个
while (i < n - 2 * k + 1) {
merge(arr, i, i + k - 1, i + 2 * k - 1);
i += 2 * k;
}
// 这段代码保证了,讲那些落单的长度不足两两merge的部分和前面merge起来
if (i < n - k) {
merge(arr, i, i + k - 1, n - 1);
}
}
private static void merge(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
// p1是左半边指针
int p1 = left;
// p2是右半边指针
int p2 = mid + 1;
// 合并后数组指针
int k = 0;
while (p1 <= mid && p2 <= right) {
if (arr[p1] < arr[p2]) {
temp[k++] = arr[p1++];
} else {
temp[k++] = arr[p2++];
}
}
while (p1 <= mid) {
temp[k++] = arr[p1++];
}
while (p2 <= right) {
temp[k++] = arr[p2++];
}
for (int i = 0; i < temp.length; i++) {
arr[left + i] = temp[i];
}
}
}
With source code: https://github.com/bruceq/leetcode.git