算法导论学习------归并排序

前面看完了插入排序和插入排序后面习题里面的选择排序,最近又把归并排序给看了。

插入排序的最坏情况为n平方,当然选择排序的恒为n平法,而归并排序则是一个nlogn的时间复杂度。当然这指的是在n无限大的情况下才可以成立,对于元素个数很小的,插入排序反而会快一些。


归并排序的主要思想就是利用了分治法把大的问题划分成相同类型,比较小规模的子问题来解决。

下面贴今天敲得代码:(在对排序好的数组进行Merge的时候,采用了两种方法,区别在于是否采用了监视哨)

//MergeSort
#include <iostream>
using namespace std;
const int MAX = 0x3f3f3f3f;
void Merge(int a[],int p,int q,int r)//带有监视哨的写法 
{
   int Lsize = q - p +1;
   int Rsize = r - q;
   int *L = new int[Lsize+1];
   int *R = new int[Rsize+1];
   
   int i = 0,j = 0;
   for(i = 0;i<Lsize;i++)
     L[i] = a[p+i];
   for(j = 0;j<Rsize;j++)
     R[j] = a[q+1+j];
     
   L[Lsize] = MAX;
   R[Rsize] = MAX;
   
   int Length = Lsize + Rsize ;
   for(i=0,j=0;i+j<Length;)
   {
   	if(L[i]<=R[j])
   		a[i+j+p] = L[i++];
    else
    	a[i+j+p] = R[j++];//这地方容易出错 
   }
   delete []R;
   delete []L;
}
void Merge2(int a[],int p,int q,int r)//不带监视哨的写法 ,主体思想都是一样的 
{
   int Lsize = q - p +1;
   int Rsize = r - q;
   int *L = new int[Lsize];
   int *R = new int[Rsize];
   
   int i = 0,j = 0;
   for(i = 0;i<Lsize;i++)
     L[i] = a[p+i];
   for(j = 0;j<Rsize;j++)
     R[j] = a[q+1+j];
     
   
   int Length = Lsize + Rsize ;
   for(i=0,j=0;i<Lsize&&j<Rsize;)
   {
   	if(L[i]<=R[j])
   		a[i+j+p] = L[i++];	
    else
    	a[i+j+p] = R[j++];//这地方容易出错 
   }
   
   while(i==Lsize&&j<Rsize)//左部完成
       a[i+j+p] = R[j++]; 
    while(j==Rsize&&i<Lsize)
       a[i+j+p] = L[i++]; 
   delete []R;
   delete []L;
	
}
void MergeSort(int a[],int p,int q)//p,q分别代表需用排序的起始与终结位置
{
	if(p<q)
	{
    int middle = (p+q)/2;
	MergeSort(a,p,middle);
	MergeSort(a,middle+1,q);
	Merge(a,p,middle,q);
	//Merge2(a,p,middle,q);
	}	
}
int main()
{
	
	int a[] = {1,2,3,123,12312,-123};
	int length = sizeof(a)/sizeof(int);
	MergeSort(a,0,length-1);
	for(int i = 0;i<length;i++)
	   cout<<a[i]<<" "; 
	return 0;
}

在监视哨的使用中使用了MAX,来表示无穷大的情况。

查阅了相关的博客,如果我们已经知道了我们需要的数的范围,那么这个max的取值就很简单了。

对于一般不知道的情况,大部分采用的是0x7fffffff,这个值在直接比较时不会有任何问题,但是如果参与运算之后再去比较就会有溢出问题。

所以另一种是采用0x3f3f3f3f。这样表示的数在加完之后不会溢出。。

参见博客:

http://blog.chinaunix.net/uid-24701781-id-3418699.html


当然这个归并排序我已经看了好几遍,自己动手写的时候还是会出现错误。。。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值