排序【4】归并排序

归并排序

1.基本思想:

   将待排序的元素分为两个长度相等的子序列,为每一个子序列排序,然后将他们合并成一个序列。合并两个子序列的过程叫做两路归并。

2.具体步骤:

  (1)按照类似于快速排序的道理,我们把待排序区间划分成两个长度想等的子区间。
  (2)递归其子区间,直到区间里面的元素只剩下一个,我们认为这个子区间已经有序。
  (3)当区间只剩下一个元素时候,每次将相邻两个区间的成一个大的有序的区间,然后一层层往上返回。
  (4)直到返回到第一层,整个区间已经有序。

3.思想流图:

4.合并步骤:

 (1)在合并的时候,首先申请空间,空间大小为合并两区间大小之和。
 (2)定义两个指针分别指向两个合并元素的第一个元素。
 (3)比较两个指针指向元素大小,将较小的放入新空间,较小的指针向后走。
 (4)当一个指针走到边界的时候,另一个指针将剩余元素放到新空间。
 (5)新空间元素满的时候,停止,合并完成。

5.实现代码:

void MergeSort(int *array, int size)
{
	assert(array);
	int *tmp = new int[size];
	_merge(array, tmp, 0, size - 1);
	delete[] tmp;

}
void _merge(int *array, int *tmp, int left, int right)
{
	if (left >= right)
		return;
	int mid = left + ((right - left) >> 1);
	_merge(array, tmp, left, mid);//递归划分左区间
	_merge(array, tmp, mid + 1, right);//递归划分右区间
	Merge(array, tmp, left, mid, right);//合并
}
void Merge(int *array, int *tmp, int left, int mid,int right)
{
	int begin1 = left;
	int end1 = mid;
	int begin2 = mid + 1;
	int end2 = right;
	int index = left;
	while (begin1 <= end1&&begin2 <= end2)
	{
		if (array[begin1] < array[begin2])
		{
			tmp[index++] = array[begin1++];
		}
		else
		{
			tmp[index++] = array[begin2++];
		}
	}
	while (begin1 <=end1)
	{
		tmp[index++] = array[begin1++];
	}
	while (begin2 <=end2)
	{
		tmp[index++] = array[begin2++];
	}
	memcpy(array, tmp, sizeof(int)*index);

}

6.非递归方式

当然我们也可以直接忽略递归划分区间的过程,从一开始就直接进行区间的归并,一样可以实现归并排序。

void Merge_sort(int *a, int length)  
{    
    int i, begin1, end1, begin2, end2, index;    
    int *tmp = new int[length];    
  
    for (i = 1; i < length; i *= 2)   
    {  
        for (begin1 = 0; begin1 < length - i; begin1 = end2)  
        {     
            begin2 = end1 = begin1 + i;    
            end2 = end1 + i;    
  
            if (end2 > length)    
                end2 = length;    
  
            index = 0;    
            while (begin1 < end1 && begin2 < end2)    
                tmp[index++] = a[begin1] > a[begin2] ? a[begin2++] : a[begin1++];    
  
            while (begin1 < end1)    
                a[--begin2] = a[--end1];    
  
            while (index > 0)    
                a[--begin2] = tmp[--index];    
        }    
    }  
    delete []tmp;  
}    

7.排序性能

时间复杂度:归并排序最好,最差,平均的时间复杂度为O(NlogN);

空间复杂度:O(N);

稳定性:稳定。

各种排序算法的比较:






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值