排序算法写完不清楚对错?对数器了解一下

840 阅读2分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

引言

最近,重新开始研究算法题,从最基础的数组排序开始搞起,什么冒泡、选择、归并一通写。调试一次没啥问题,提交就是不通过,大大打击了自信心。既然自己写的不一定对,那JDK提供的数组排序总是经过检验没有问题,如果样本随机且足够大,自己写的排序和JDK提供的结果一致,那说明写的没有啥问题。

数组排序对数器

以自己写的选择排序为例。代码如下:

private static void selectSort(int[] array){
	for (int i = 0; i < array.length; i++) {
		for (int j = i + 1; j < array.length; j++) {
			if (array[j]<array[i]){
				swap(array,i,j);
			}
		}
	}
}

/**
 * 交换数组i和j位置的值
 * @param array 数组
 * @param i 位置
 * @param j 位置
 */
private static void swap(int[] array,int i,int j){
	array[i] = array[i] ^ array[j];
	array[j] = array[i] ^ array[j];
	array[i] = array[i] ^ array[j];
}

这里的swap方法是通过异或运算实现数组中两个位置元素的交换,但是有个前提是i!=j

JDK的排序算法

有了不知对错的排序算法,需要JDK提供的绝对正确的排序方法。

public static void comparator(int[] arr) {
	Arrays.sort(arr);
}

随机样本生成

随机产生数组,作为排序比较的样本。

public static int[] generateRandomArray(int maxSize, int maxValue) {
	//产生随机数范围为[0,maxSize]
	int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
	for (int i = 0; i < arr.length; i++) {
		//产生[-maxValue,maxValue]的元素
		arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
	}
	return arr;
}

拷贝数组

一个数组,需要使用两个方法进行排序,则需要将数组拷贝,生成相同的数组。

public static int[] copyArray(int[] arr) {
	if (arr == null) {
		return null;
	}
	int[] res = new int[arr.length];
	System.arraycopy(arr, 0, res, 0, arr.length);
	return res;
}

对比方法

两次排序结束后,结果是否一致,需要对比方法进行比较。

public static boolean isEqual(int[] arr1, int[] arr2) {
	if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
		return false;
	}
	if (arr1 == null && arr2 == null) {
		return true;
	}
	if (arr1.length != arr2.length) {
		return false;
	}
	for (int i = 0; i < arr1.length; i++) {
		if (arr1[i] != arr2[i]) {
			return false;
		}
	}
	return true;
}

执行比较

public static void main(String[] args) {
	int maxSize = 100;
	int maxValue = 100;
	int testTime = 500000;
	boolean succeed = true;
	for (int i = 0; i < testTime; i++) {
		int[] arr1 = generateRandomArray(maxSize, maxValue);
		int[] arr2 = copyArray(arr1);
		selectSort(arr1);
		comparator(arr2);
		if (!isEqual(arr1, arr2)) {
			succeed = false;
			break;
		}
	}
	System.out.println(succeed);
}

总结

使用对数器能检验数组排序算法是否准确,就是将准确排序算法和不确定排序算法,在足够多的样本量里对结果进行对比,确定算法是比较精准,还是某些特定数据的假象。