Java中数组合并阶段的排序逻辑及存储方式疑问
Java中数组合并阶段的排序逻辑及存储方式疑问
嗨,我看你在复习归并排序的时候,对合并阶段的排序存储逻辑有点摸不清,先帮你理一理——你贴的这段代码其实只是把两个数组简单拼接成一个新数组,完全没有做排序操作哦!这可能是你混淆的关键点~
先拆解下你这段代码的逻辑:
- 它先创建了一个长度等于两个输入数组之和的新数组
c - 第一个for循环把数组
a的元素原封不动按顺序放到c的前半部分 - 第二个for循环把数组
b的元素直接接在c的后半部分 - 最后打印的结果只是两个数组的拼接产物,看起来有序只是因为你选的
a和b本身就是各自有序的——要是你把a改成[30,10,20],运行结果就会是[30,10,20,40,50,60,70,80],完全没有排序效果
那归并排序里真正的合并阶段,是怎么实现有序存储的呢?
归并排序的核心是“分而治之”,合并阶段的大前提是要合并的两个子数组已经是各自有序的,这时候的有序合并存储逻辑是这样的:
- 先创建一个和合并后总长度一致的临时数组(用来存放有序的合并结果)
- 用三个指针:
i指向第一个有序子数组的起始位置,j指向第二个有序子数组的起始位置,k指向临时数组的起始位置 - 循环比较两个子数组当前指针位置的元素:
- 如果第一个子数组的当前元素更小(或相等),就把它放到临时数组的
k位置,然后i和k都往后挪一位 - 否则就把第二个子数组的当前元素放到
k位置,j和k往后挪一位
- 如果第一个子数组的当前元素更小(或相等),就把它放到临时数组的
- 当其中一个子数组的元素都被处理完了,把另一个子数组剩下的元素直接依次拷贝到临时数组的剩余位置
- 最后这个临时数组就是合并后的有序数组,你可以把它拷贝回原数组(如果是原地归并场景)或者直接使用
给你写个归并排序合并阶段的示例代码,一看就懂:
import java.util.Arrays; public class MergeSortedArrays { public static void main(String[] args) { int[] a = {10, 30, 50}; int[] b = {20, 40, 60, 70}; int[] merged = mergeSortedArrays(a, b); System.out.println(Arrays.toString(merged)); // 输出 [10,20,30,40,50,60,70] } public static int[] mergeSortedArrays(int[] a, int[] b) { int aLen = a.length; int bLen = b.length; int[] merged = new int[aLen + bLen]; int i = 0, j = 0, k = 0; // 同时遍历两个有序子数组,按大小顺序填充临时数组 while (i < aLen && j < bLen) { if (a[i] <= b[j]) { merged[k++] = a[i++]; } else { merged[k++] = b[j++]; } } // 处理第一个子数组剩下的元素 while (i < aLen) { merged[k++] = a[i++]; } // 处理第二个子数组剩下的元素 while (j < bLen) { merged[k++] = b[j++]; } return merged; } }
简单总结下:你之前的代码只是数组拼接,没有排序逻辑;而归并排序的合并阶段是基于两个已有序的子数组,通过双指针比较的方式,有序地填充临时数组,最终得到的才是合并后的有序数组——这就是两者的本质区别啦!
备注:内容来源于stack exchange,提问作者April_Nara
相关产品推荐
相关产品推荐

