赞
踩
需求:
排序前:{8,4,5,7,1,3,6,2}
排序后:{1,2,3,4,5,6,7,8}
排序原理:
代码
package study.sort; public class Merge { //归并排序所需要的辅助数组 private static Comparable[] assist; //对数组内的元素进行排序 public static void sort(Comparable[] a){ assist = new Comparable[a.length]; int lo = 0; int hi = a.length - 1; sort(a,lo,hi); } //对数组a中从索引lo到索引hi之间的元素进行排序 private static void sort(Comparable[] a,int lo,int hi){ //只有一个数据,不用排序了 if (hi <= lo){ return; } int mid = lo + (hi - lo) / 2; //对lo到mid之间的元素进行排序 sort(a,lo,mid); //对mid + 1到hi之间的元素进行排序 sort(a,mid + 1,hi); //对lo到mid这组数据和mid到hi这组数据进行归并 merge(a,lo,mid,hi); } //从索引lo到所以mid为一个子组,从索引mid+1到索引hi为另一个子组, // 把数组a中的这两个子组的数据合并成一个有序的大组(从索引lo到索引hi) private static void merge(Comparable[] a,int lo,int mid,int hi){ //lo到mid这组数据和mid + 1到hi这组数据归并到辅助数组assist对应的索引处 int i = lo;//定义一个指针,指向assist数组中开始填充数据的索引 int p1 = lo;//定义一个指针,指向第一组数据的第一个元素 int p2 = mid + 1;//定义一个指针,指向第二组数据的第一个元素 //比较左边小组和右边小组中的元素大小,哪个小,就把哪个数据填充到assist数组中 while (p1 <= mid && p2 <= hi){ if (less(a[p1],a[p2])){ assist[i++] = a[p1++]; }else { assist[i++] = a[p2++]; } } //上面的循环结束后,如果退出循环的条件是p1 > mid,则证明左边小组中的数据已经归并完毕, // 如果退 出循环的条件是p2 > =hi,则证明右边小组的数据已经填充完毕; // 所以需要把未填充完毕的数据继续填充到assist中, // 下面两个循环,只会执行其中的一个 while (p1 <= mid){ assist[i++] = a[p1++]; } while (p2 <= hi){ assist[i++] = a[p2++]; } //那么现在,assist数组中,从lo到hi的元素是有序的,再把数据拷贝到a数组中对应的索引处 for (int index = lo; index <= hi ; index++) { a[index] = assist[index]; } } //判断v是否小于w private static boolean less(Comparable v, Comparable w) { return v.compareTo(w) < 0; } //交换a数组中,索引i和索引j处的值 private static void exchange(Comparable[] a, int i, int j) { Comparable temp = a[i]; a[i] = a[j]; a[j] = temp; } }
package study.Test; import study.sort.Merge; import java.util.Arrays; public class MergeTest { public static void main(String[] args) { Integer[] a = {8, 4, 5, 7, 1, 3, 6, 2}; System.out.println("排序前:" + Arrays.toString(a)); Merge.sort(a); System.out.println("排序后:" + Arrays.toString(a)); } }
效果图
归并排序的缺点:
需要申请额外的数组空间,导致空间复杂度提升,是典型的以空间换时间的操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。