归并排序的核心思想是将需要排序的数据(通常是数组),切分成不同的小段,对每一段数据先在内部排序,然后将各个段再进行合并排序,比如给定一个数组[2,1,4,3],可以先将数组切分成两个小数组也就是[2,1]和[4,3],然后分别对两个小数组进行内部排序,也就是排成[1,2]和[3,4],然后再对这两个小数组进行合并排序,在对这两个小数组合并排序的时候,我们按照这个步骤来操作:
新建一个数组,长度是总数组的长度,也就是4,我们记这个数组为help
分别有两个指针P1和P2指向两个小数组的第一个元素,然后移动两个指针,哪个数组对应的指针所指的数据小,就将它拷贝到help当中,如果有一个指针先移动结束,那么另一个数组当前指针所指的位置以及后面的数据直接拷贝到help即可
将help数组的数据还原到原数组中
代码实现:
- private void mergeSort(int[] arr, int start, int end) {
- if (start == end) {
- return;
- }
- int middle = start + ((end - start) >> 1);
- mergeSort(arr, start, middle);
- mergeSort(arr, middle + 1, end);
- merge(arr, start, middle, end);
- }
-
- private void merge(int[] arr, int start, int middle, int end) {
- System.err.println(start + ":" + middle + ":" + end);
- int i = 0;
- int[] help = new int[end - start + 1];
- int index1 = start;
- int index2 = middle + 1;
- while (index1 <= middle && index2 <= end) {
- help[i++] = arr[index1] <= arr[index2] ? arr[index1++] : arr[index2++];
- }
- while (index1 <= middle) {
- help[i++] = arr[index1++];
- }
- while (index2 <= end) {
- help[i++] = arr[index2++];
- }
- int length = help.length;
- for (int i1 = 0; i1 < length; i1++) {
- arr[start + i1] = help[i1];
- }
- }
-
- @Test
- public void mergeSort() {
- int[] array = new int[]{3, 2, 5, 4};
- int length = array.length;
- mergeSort(array, 0, length - 1);
- }