简单手撕一个归并排序:
归并排序的思想不用多讲,去看其他人的博客即可,本文只简单复现归并排序并且进行案例测试。
整体代码:
public void mergeSort(int[] arrays) {//先传入一个任意顺序的数组,进行排序
if (arrays.length == 1) return ;
int mid = arrays.length / 2;
mergeSort0(arrays, 0, mid);
mergeSort0(arrays, mid, arrays.length);
migrate(arrays,0,mid, arrays.length);
}
private void mergeSort0(int[] arrays, int left, int right) {//这里简单来实现一下。
if (right - left == 1) return;
int mid = (right + left) / 2;
mergeSort0(arrays, left, mid);
mergeSort0(arrays, mid, right);
migrate(arrays,left,mid,right);
}
private void migrate(int[] arrays, int left, int mid, int right) {
//迁移
int len = right - left;
int[] ints = new int[len];
int index1 = left;
int index2 = mid;
for (int i = 0; i < len; i++) {
if (index1 == mid) {
len = i;
break;
}
if (index2 == right) {
System.arraycopy(arrays, index1, ints, i, len - i);
break;
}
if (arrays[index1] >= arrays[index2]) {
ints[i] = arrays[index2];
index2++;
} else {
ints[i] = arrays[index1];
index1++;
}
}
System.arraycopy(ints, 0, arrays, left, len);//这里是调用底层的JNI,但是可以优化一下,因为如果copy的长度小于2,那么调用JNI的效率有点低
}
本地测试:
@Test
public void testMyMergeSort() {
int[][] arr = {
{1, 4, 2, -1, 3, 9, 7},
};
for (int i = 0; i < arr.length; i++) {
System.out.printf(Arrays.toString(arr[i]) + " ` result is " );
mergeSort(arr[i]);
System.out.println(Arrays.toString(arr[i]));
}
}
完整代码:
import org.junit.Test;
import java.util.Arrays;
/**
* @author xin麒
* @date 2023/3/23 18:57
* 这个应该是可以的了,就差去leetcode测试了
*/
public class MyMergeSort {
public void mergeSort(int[] arrays) {//先传入一个任意顺序的数组,进行排序
if (arrays.length == 1) return ;
int mid = arrays.length / 2;
mergeSort0(arrays, 0, mid);
mergeSort0(arrays, mid, arrays.length);
migrate(arrays,0,mid, arrays.length);
}
private void mergeSort0(int[] arrays, int left, int right) {//这里简单来实现一下。
if (right - left == 1) return;
int mid = (right + left) / 2;
mergeSort0(arrays, left, mid);
mergeSort0(arrays, mid, right);
migrate(arrays,left,mid,right);
}
private void migrate(int[] arrays, int left, int mid, int right) {
//迁移
int len = right - left;
int[] ints = new int[len];
int index1 = left;
int index2 = mid;
for (int i = 0; i < len; i++) {
if (index1 == mid) {
len = i;
break;
}
if (index2 == right) {
System.arraycopy(arrays, index1, ints, i, len - i);
break;
}
if (arrays[index1] >= arrays[index2]) {
ints[i] = arrays[index2];
index2++;
} else {
ints[i] = arrays[index1];
index1++;
}
}
System.arraycopy(ints, 0, arrays, left, len);//这里是调用底层的JNI,但是可以优化一下,因为如果copy的长度小于2,那么调用JNI的效率有点低
}
@Test
public void testMyMergeSort() {
int[][] arr = {
{1, 4, 2, -1, 3, 9, 7},
};
for (int i = 0; i < arr.length; i++) {
System.out.printf(Arrays.toString(arr[i]) + " ` result is " );
mergeSort(arr[i]);
System.out.println(Arrays.toString(arr[i]));
}
}
}
在本地测试是远远不够的·,我们可以借助leetcode平台来测试,找到之前写过的一个题解(56条消息) 287寻找重复数-hot100-java_xin麒的博客-CSDN博客
这里的思路1就用到了对数组的排序,于是打开leetcode平台287. 寻找重复数 - 力扣(LeetCode)
直接将题解改成归并排序;来测试:
class Solution {
public int findDuplicate(int[] nums) {
int[] myNum = new int[nums.length];
for (int i = 0; i < nums.length; i++) myNum[i] = nums[i];
mergeSort(myNum);
for (int i = 1; i < myNum.length; i++) {
if (myNum[i] == myNum[i - 1]) return myNum[i];
}
return 0;
}
public void mergeSort(int[] arrays) {//先传入一个任意顺序的数组,进行排序
if (arrays.length == 1) return ;
int mid = arrays.length / 2;
mergeSort0(arrays, 0, mid);
mergeSort0(arrays, mid, arrays.length);
migrate(arrays,0,mid, arrays.length);
}
private void mergeSort0(int[] arrays, int left, int right) {//这里简单来实现一下。
if (right - left == 1) return;
int mid = (right + left) / 2;
mergeSort0(arrays, left, mid);
mergeSort0(arrays, mid, right);
migrate(arrays,left,mid,right);
}
private void migrate(int[] arrays, int left, int mid, int right) {
//迁移
int len = right - left;
int[] ints = new int[len];
int index1 = left;
int index2 = mid;
for (int i = 0; i < len; i++) {
if (index1 == mid) {
len = i;
break;
}
if (index2 == right) {
System.arraycopy(arrays, index1, ints, i, len - i);
break;
}
if (arrays[index1] >= arrays[index2]) {
ints[i] = arrays[index2];
index2++;
} else {
ints[i] = arrays[index1];
index1++;
}
}
System.arraycopy(ints, 0, arrays, left, len);//这里是调用底层的JNI,但是可以优化一下,因为如果copy的长度小于2,那么调用JNI的效率有点低
}
}
这里测试是通过的,不信可以尝试下,leetcode这么多的测试用例都通过了,那么说明应该是没问题了。思路写对了,剩下的就是局部代码的优化了,因为本篇只复现归并排序,其他的就简单处理下算了。