归并算法的思想
先将数组递归分组,然后合并结果,换成伪码可表示为
MergeSort(origin) = MergeSort(MergeSort(left), MergeSort(right))
链表的归并排序代码结构更加贴合上述伪码
Java 数组归并算法实现
package com.study;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args){
int[] origin = {1,9,10,15,2,8,4,45};
MergeSort mergeSort = new MergeSort();
Arrays.stream(mergeSort.sort(origin, 0, origin.length - 1))
.forEach(System.out :: println);
}
public int[] sort(int[] origin, int low, int high){
int middle = (low + high) / 2;
if (low < high) {
sort(origin, low, middle);
sort(origin, middle+1, high);
merge(origin, low, middle, high);
}
return origin;
}
private void merge(int[] origin, int low, int mid, int high){
int[] temp = new int[high - low + 1];
int i = low;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= high) {
if (origin[i] <= origin[j]) {
temp[k++] = origin[i++];
} else {
temp[k++] = origin[j++];
}
}
while (i <= mid) {
temp[k++] = origin[i++];
}
while (j <= high) {
temp[k++] = origin[j++];
}
for (int x=0; x<temp.length; x++) {
origin[x + low] = temp[x];
}
}
}
Java 链表归并算法实现
package com.study;
import java.util.Objects;
public class LinkedMergeSort {
public static void main(String[] args){
ListNode head = new ListNode(3);
ListNode node2 = new ListNode(10);
ListNode node3 = new ListNode(4);
ListNode node4 = new ListNode(5);
head.next = node2;
node2.next = node3;
node3.next = node4;
LinkedMergeSort linkedMergeSort = new LinkedMergeSort();
ListNode result = linkedMergeSort.sort(head);
while (!Objects.isNull(result)) {
System.out.println(result.val);
result = result.next;
}
}
public ListNode sort(ListNode head){
if (Objects.isNull(head)) {
return head;
}
ListNode middle = getMiddle(head);
ListNode right = middle.next;
middle.next = null;
return merge(head, right);
}
private ListNode getMiddle(ListNode head){
ListNode slow = head;
ListNode fast = head.next;
while (!Objects.isNull(fast) && !Objects.isNull(fast.next)) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
private ListNode merge(ListNode left, ListNode right){
if (Objects.isNull(left)) {
return right;
}
if (Objects.isNull(right)) {
return left;
}
ListNode head;
if (left.val <= right.val) {
head = left;
head.next = merge(left.next, right);
} else {
head = right;
head.next = merge(left, right.next);
}
return head;
}
}
class ListNode {
int val;
ListNode next;
ListNode(int val){
this.val = val;
}
}
完整代码地址:https://github.com/BoyQiang/personal-code-learning/tree/master/personal-code-learning-algorithm