算法导论之归并排序


将一个含有n个序列的有序表看成是n个长度为1的有序表,然后两两归并,得到[n/2]个长度为2的有序表,然后再两两归并,直到得到一个长度为n的有序表为止。

下面是归并排序的一个简单的例子:

初始值 【49】 【38】 【65】 【97】 【76】 【13】 【27】 
看成由长度为1的7个子序列组成 
第一次合并之后 【38 49】 【65 97】 【13 76】 【27】 
看成由长度为1或2的4个子序列组成 
第二次合并之后 【38 49 65 97】 【13 27 76】 
看成由长度为4或3的2个子序列组成 
第三次合并之后 【13 27 38 49 65 76 97】

package sort;
public class MergeSort {

	 /**
	  * 归并排序 先将初始的序列表看成是n个长度为1的有序表 
	  * (1)定义指针i,指向第一个序列表的第一个元素
	  * (2)定义指针j,指向第二个序列表的第一个元素
	   * (3)比较i,j指向的元素大小,若前者大,将后者插入到新表中 否则,把前者插入到后表中
	  * (4)直到取完第一个序列表或者第二个序列表为止
	  */

	 public static void main(String[] args) {
	  // TODO Auto-generated method stub

	  int[] num = { 51, 38, 49, 27, 62, 05, 16 };
	  int[] num1 = new int[7];
	  num = mergesort(num, 0, num.length - 1, num1);

	  for (int i : num) {
	   System.out.print(i + " ");
	  }

	 }

	 
	 private static int[] mergesort(int[] num, int s, int t, int[] num1) {

	  int m;
	  int[] num2 = new int[t + 1];
	  if (s == t)//只有一个元素要排序
	   num1[s] = num[s];

	  else {
	   m = (s + t) / 2;
	   mergesort(num, s, m, num2);//左半部分递归调用
	   mergesort(num, m + 1, t, num2);//右半部分递归调用
	   merg(num2, s, m, t, num1);// 由num2去归并,返回的值放到num1中,num1赋新值,其实就是更新num2,然后让num2再去归并,返回新的num1
	   	//mergesort最底层的时候计算的num2是数组,
	   //最底层返回num2=num1【0】=num【0】=51  num2=num1【1】=num【1】=38
	   //运算完每层的两个mergesort,得到num2左半部分和num2右半部分,num2合起来带到merg里面计算
	  }

	  return num1;
	 }

	//有序表的合并

	 private static void merg(int[] num, int l, int m, int n, int[] num1) {//l---m,m+1---n
	  System.out.print("l=" + l + " m=" + m + " n=" + n);
	  System.out.println();
	  int i, j, k;
	  i = l;
	  j = m + 1;
	  k = l;
	  while (i <= m && j <= n) {
	   if (num[i] < num[j])//比较左边的第一个和右边的第一个
	    num1[k++] = num[i++];
	   else {
	    num1[k++] = num[j++];
	   }
	  }

	  while (i <= m) {//当上面j跳出循环,也就是右边的合并结束了,直接把左边的接在后面
	   num1[k++] = num[i++];
	  }
	  while (j <= n) {//当上面i跳出循环,也就是左边的合并结束了,直接把右边的接在后面
	   num1[k++] = num[j++];
	  }

	 }

	}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值