记归并排序与其先赋值后自增问题
归并排序
- 归并排序的理论就不叙述了,直接不如正题。
- 一个例子示例什么是归并排序:
- 先讲数组划分为左右两个子表:
- 然后继续左右两个子表拆分:
- 对最后的拆分的子表,两两进行排序:
- 对有序的子表进行排序和比较合并:
- 对合并后的子表继续比较合并:
- 可能前面的分割很清楚,但是后面的合并就有些模糊了,是怎么进行合并的呢?看代码:
/**
* 类说明:归并排序
*/
public class MergeSort {
public static int[] sort(int[] array) {分割排序
if(array.length<=MakeArray.THRESHOLD){
return InsertionSort.sort(array); //简单的插入排序
}else{
/*切分数组,然后递归调用*/
int mid = array.length / 2;
int[] left = Arrays.copyOfRange(array, 0, mid);
int[] right = Arrays.copyOfRange(array, mid, array.length);
return merge(sort(left), sort(right));
}
}
/**
* 归并排序——将两段排序好的数组结合成一个排序数组
*
* @param left
* @param right
* @return
*/
public static int[] merge(int[] left, int[] right) {//合并
int[] result = new int[left.length + right.length];
for (int index = 0, i = 0, j = 0; index < result.length; index++) {
if (i >= left.length)/*左边数组已经取完,完全取右边数组的值即可*/
result[index] = right[j++];
else if (j >= right.length)/*右边数组已经取完,完全取左边数组的值即可*/
result[index] = left[i++];
else if (left[i] > right[j])/*左边数组的元素值大于右边数组,取右边数组的值*/
result[index] = right[j++];
else/*右边数组的元素值大于左边数组,取左边数组的值*/
result[index] = left[i++];
}
return result;
}
public static void main(String[] args) {
System.out.println("============================================");
long start = System.currentTimeMillis();
MergeSort.sort(MakeArray.makeArray());
System.out.println(" spend time:"+(System.currentTimeMillis()-start)+"ms");
}
}
- 重点看merge函数部分:
public static int[] merge(int[] left, int[] right) {//合并
int[] result = new int[left.length + right.length];
for (int index = 0, i = 0, j = 0; index < result.length; index++) {
if (i >= left.length)/*左边数组已经取完,完全取右边数组的值即可*/
result[index] = right[j++];
else if (j >= right.length)/*右边数组已经取完,完全取左边数组的值即可*/
result[index] = left[i++];
else if (left[i] > right[j])/*左边数组的元素值大于右边数组,取右边数组的值*/
result[index] = right[j++];
else/*右边数组的元素值大于左边数组,取左边数组的值*/
result[index] = left[i++];
}
return result;
}
-
这是一个升序的,上面的例子是降序。他是这样进行合并排序的。
-
好了合并排序弄明白了,剩下的也就是递归回去了。
-
但是发现这个代码中又有一个的点:
result[index] = right[j++];
,为什么会是j++
不是应该是result[index] = right[j]
吗?后来一想,应该是,但是只不过j
的自增是在赋值后操作的!
result[index] = right[j]
赋值后自增
- 证明:
/**
*CLASSNAME:Test
* 测试排序中的 i++
* 如: result[index] = right[j++]; 新数组中的元素是等于right中的第一个元素还是第二个元素(假设j=0)
*/
public class Test {
public static void main(String[] args) {
int[] result = new int[5];
int[] right = {1,2,3,4,5};
System.out.println("初始数组:");
System.out.println("=======================================");
System.out.println(result.toString());
for (int i = 0, j = 0; i < result.length; i++){
// if (j > right.length){
//right数组会出现越界吗?在这里肯定不会,因为result的长度也是5,会先退出循环而不会执行到取right[j++]这个地方
// System.out.println("结束!");
// }else{
System.out.println("right["+j+"] = " +right[j]);
result[i] = right[j++];
System.out.println("result["+i+"] = "+result[i]);
// }
}
}
}
-
结果:
-
可以发现 j++ 操作是在赋值后进行的!!