三、排序_03 &归并排序(笔记)

import java.util.Arrays;
import java.util.Random;

public class A009_归并排序 {

	public static void main(String[] args) {
		int len = 10;
		int max = 20;
		int[] arr = getRandomArr(len, max);
		System.out.println(Arrays.toString(arr));
		sort(arr, 0, len - 1);
		System.out.println(Arrays.toString(arr));
	}

	public static void sort(int[] arr, int left, int right) {
		if (left < right) {
			int mid = (left + right) / 2;
			sort(arr, left, mid);
			sort(arr, mid + 1, right);
			merge(arr, left, mid, right);
		}
	}

	public static void merge(int[] arr, int left, int mid, int right) {
		int[] help = new int[right + 1];
		copy(arr, help, left, right);
		System.out.println(Arrays.toString(help) + "  " + left + " " + mid + " " + right);
		int l = left;
		int r = mid + 1;
		int cur = left;
		while (l <= mid && r <= right) {
			if (help[l] <= help[r]) {
				arr[cur] = help[l];
				l++;
				cur++;
			} else {
				arr[cur] = help[r];
				r++;
				cur++;
			}
		}
		while (l <= mid) {
			arr[cur] = help[l];
			l++;
			cur++;
		}
		while (r <= right) {
			arr[cur] = help[r];
			r++;
			cur++;
		}
	}

	public static void copy(int[] arr, int[] help, int p, int right) {
		while (p <= right) {
			help[p] = arr[p];
			p++;
		}
	}

	public static int[] getRandomArr(int len, int max) {
		int[] arr = new int[len];
		Random ran = new Random(max);
		for (int i = 0; i < len; i++) {
			arr[i] = ran.nextInt(max) + 1;
		}
		return arr;
	}
}

这里还是用随机数来生成数组,然后是用递归进行层次划分,这里可以看图
在这里插入图片描述
归并排序是将数组中这一个段内的元素复制到一个新数组中,然后从两段数组的头读到元素,进行比较,这里对应的就是先用sort函数进行折半,在其返回的时候,进行合并,合并用到了merge。
我将merge的每一步的数组都打印了出来,方便查看,这里用copy函数,把arr数组中,left到right的所有值,都复制给help,可以看到打印出的help数组,有很多元素都是0,这个要对应着下一段看👇
可以看到,第一次的help数组只有两个元素,然后left、mid、right的值是0、0、1,也就是第一第二个元素,分别是第一段和第二段,然后对他们进行比较,并按顺序插入,然后之后的每一步都是这样;那么如果是0的话,就要再看3个下标的值了,可以观察一下,正数第四行的[0,0,0,2,6] 3 3 4,非0的那个下标,正好就是left=3,也就是说,并不会把前面的0,也加入到arr数组中,接下来讲循环。
第一个while循环是对两个指针都进行判断,比如,我们看倒数第三行[0, 0, 0, 0, 0, 14, 16, 16, 9, 14] 5 7 9,着两个数组是
A:14,16,16
B:9,14
这时候还要看l和r,他们分别对应的值是5和8,也就是A的第一个元素,和B的第一个元素,把这两个进行比较,那么就是把B的第一个元素放入arr数组中了,那么这时候,cur 的下标就是left,也就是5,放进去之后,l++还有cur++;之后也是反复,那么接下来要讲另一种情况;
同样也是上面的A,B例子当这个循环进行完后,B的元素先被放完,这时候,A中还有剩余的元素没放进arr数组,那么就用到了下面的两个循环,哪一组没放进去,那就把那一组的剩下的所有值,都放进去,其实与第一个循环相差没多少。
那么这就是完整的归并排序了,代码看着多,但也是重复的部分比较多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值