归并排序
采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。
核心思想是分治
- 1.先是两个一组,组内有序
- 2.第二次,取两个组,
- **比较头部,**小的放进来,原属组删除,在比较新的头,注意不是两个头比较了按序进两个,而是只进一个
- 直到有一个组空,直接加进来
- 这样就是每趟组合排序复杂度是O(N),有log N趟,第一趟分成两个一组,第二次四个一组,N/4,每次都是合并二的倍数,所以复杂度N*log N
- 时间复杂度稳定
代码实现
package com.qcby.sort;
public class Merge {
static class Node {
public int value;
public Node next;
@Override
public String toString() {
return "Node{" +
"value=" + value +
", next=" + next +
'}';
}
}
public static void main(String[] args) {
int[] nums = new int[]{53, 56, 24, 86, 45, 41};
sort(nums);
}
public static void sort(int[] arr) {
Node[] node = new Node[arr.length];
for (int i = 0; i < arr.length; i++) {
Node no = new Node();
no.value = arr[i];
node[i] = no;
}
for (; ; ) {
int newLength = node.length / 2;
if (newLength * 2 < node.length) {
newLength += 1;
}
Node[] arrNew = new Node[newLength];
int index = 0;
for (int i = 0; i < node.length; ) {
Node node1 = node[i];
if (i + 1 >= node.length) {
arrNew[index] = node1;
break;
}
Node node2 = node[i + 1];
Node res = merge(node1, node2);
i += 2;
arrNew[index] = res;
index++;
}
node = arrNew;
if (newLength == 1) {
break;
}
}
System.out.println(node[0]);
}
public static Node merge(Node node1, Node node2) {
Node res = null;
if (node1.value <= node2.value) {
res = node1;
node1 = node1.next;
} else {
res = node2;
node2 = node2.next;
}
Node flag = res;
while (node1 != null) {
if (node2 != null) {
if (node1.value < node2.value) {
flag.next = node1;
node1 = node1.next;
} else {
flag.next = node2;
node2 = node2.next;
}
} else {
flag.next = node1;
break;
}
flag = flag.next;
}
if (node2 != null) {
flag.next = node2;
}
return res;
}
}