[算法]递归算法中sort的递归理解以及原地归并和自顶向下递归排序

递归算法其实就是拆解+归并才是完整的,不能单看把两个有序数组归并,而是学会拆分,我……

递归算法里有个非常烧脑的……大概我脑子不好的递归理解

就是那个双层嵌套的sort递归,我实在无法理解,所以画了个图,来排{9084}这四个数

就是

一开始完全不理解这也能递归??画图后果然清晰多了

打印一共执行了三次原地归并,我却不知道怎么来的……所以……

	private static void sort(Comparable[] a, int lo, int hi) {
		if (hi <= lo)
			return;//检查下标
		
		int mid = lo + (hi - lo) / 2;//确定中间值
		sort(a, lo, mid);// 将左边排序
		sort(a, mid + 1, hi);// 将右边排序
		merge(a, lo, mid, hi);
		System.out.println(Arrays.toString(a));

	}


所以每一个return或者执行完一次归并就会跳出这层递归而不是单纯的循环执行。

理解这个算法首先要学会拆解,它的确实现了拆解,具体自行意会吧。

接下来上源码

package Chapter2_2.MergeSort;

import java.util.Arrays;

import Chapter2_1.ElementarySorts.Example;
import Chapter2_1.ElementarySorts.Shell;
import edu.princeton.cs.algs4.In;

public class Merge extends Example {

	/*
	 * 原地归并的抽象方法+自顶向下的归并排序
	 */

	@SuppressWarnings("rawtypes")

	private static Comparable[] aux;

	/*
	 * 原地归并的抽象方法 将(一个数组分割为两个)不同的两个有序数组归并到第三个数组中。
	 */
	public static void merge(Comparable[] a, int lo, int mid, int hi) {

		int i = lo, j = mid + 1;// i是左边,j是右边
		for (int k = lo; k <= hi; k++) {
			aux[k] = a[k];// 将a复制到aux里

		}

		for (int k = lo; k <= hi; k++) {// 用左边左边要递增,用右边右边要递增
			if (i > mid) {
				a[k] = aux[j++];
			} // 左半边用尽取右半边的元素
			else if (j > hi) {
				a[k] = aux[i++];
			} // 右半边用尽取左半边的元素
			else if (less(aux[j], aux[i])) {// 当前元素小于左边的当前元素则取右半边的元素
				a[k] = aux[j++];
			} else {
				a[k] = aux[i++];
			}

		}

	}

	public static void sort(Comparable[] a) {
		aux = new Comparable[a.length];// 一次性分配空间
		sort(a, 0, a.length - 1);
	}

	private static void sort(Comparable[] a, int lo, int hi) {
		if (hi <= lo)
			return;//检查下标
		
		int mid = lo + (hi - lo) / 2;//确定中间值
		sort(a, lo, mid);// 将左边排序
		sort(a, mid + 1, hi);// 将右边排序
		merge(a, lo, mid, hi);
		System.out.println(Arrays.toString(a));

	}
	
	public static void main(String[] args) {
		String[] a = In.readStrings();
		sort(a);
		assert isSorted(a);
		show(a);
		
	}

}

猜你喜欢

转载自blog.csdn.net/qq_38277033/article/details/79618594
今日推荐