程序员面试题精选--归并排序

采用分治策略

一般有三个步骤:

1、分解:将n个元素分成各含n/2个元素的子序列

2、解决:用合并排序法对两个子序列递归的排序

3、合并:合并两个已排序的子序列以得到排序结果。

在归并排序时,其长度为1时递归结束。单个元素被视为是已排序好的。

参考代码如下:

#include<iostream>
using namespace std;

#define MAX 0x7FFFFFFF			//最大可能值,用于哨兵 

void Merge(int *A, int low, int mid, int high)
{
	if(A == NULL)return;
	
	int n1 = mid-low+1;
	int n2 = high-mid;
	int *left = new int[n1+1];
	int *right = new int[n2+1];
	for(int i=0; i<n1; i++)
		left[i] = A[i+low];
	for(int j=0; j<n2; j++)
		right[j] = A[j+mid+1];
		
	//哨兵元素 
	left[n1] = MAX;
	right[n2] = MAX;
	
	//将left[low...mid]和right[mid+1, high]共high-low+1 个元素有序合并 
	int i=0,j=0;
	for(int k=low; k<=high; k++)
	{
		if(left[i]<=right[j])
		{
			A[k] = left[i];
			i++;
		}
		else
		{
			A[k] = right[j];
			j++;
		}
	}
}

//归并排序 
void Merge_Sort(int *A, int low, int high)
{
	if(low<high)
	{
		int mid = (low+high)/2;
		Merge_Sort(A, low, mid);
		Merge_Sort(A, mid+1, high);
		Merge(A, low, mid, high);
	}
}

void Print(int *A, int low, int high)
{
	for(int i=low; i<=high; i++)
		cout<<A[i]<<" ";
	cout<<endl;
}

int main()
{
	int array[11] = {3, 5, 1, 9, 20, 4, 13, 6, 4, 12, 8};
	int low = 0;
	int high = sizeof(array)/sizeof(int)-1;
	Merge_Sort(array, low, high);
	Print(array, low, high);
	system("pause");
	return 0;
}

算法分析

(1)稳定性

 归并排序是一种稳定的排序。

(2)存储结构

可用顺序存储结构。也易于在链表上实现。

(3)时间复杂度

对长度为n的文件,需进行 趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。

(4)空间复杂度

需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值