算法笔记2——归并排序

1、归并排序思想

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。

  将n个数,分成两部分,只要这两部分都已经排好序,那么合并这两部分的时间复杂度就只要O(N)。如a[1,3,4]和b[2,4,5,6],每次只要在a拿出一个,在b拿出一个比较,然后将小的放入临时c中,a或b为空时,只需要把另一个不为空的所剩下的都追加到c后面即可,因为a和b是有序的。

这样利用上面的方法,只要将n个数分成两组,这两组在分成两组,一直递归到只有两个数,将这两个数合并,一直递归回去。这样递归回的两部分都是排序好的。如图:

2、归并排序效率

设数列长为N,将数列逐步分解成两部分一共要logN步,每步都是一个合并有序数列的过程,合并的时间复杂度可以记为O(N),故一共为O(N*logN)。

空间复杂度为 O(N)

比较次数介于(NlogN)/2和(NlogN)-N+1,赋值操作的次数是(2NlogN)。

归并排序比较占用内存,但却是一种效率高且稳定的算法。

3、归并排序实现

a)C实现

void Merge(int* arr, int start, int mid, int end)//合并arr[start,mid],arr[mid+1,end],且两边都是有序的
{
	int nlen = end - start + 1;
	int* pTemp = (int*)malloc(nlen * sizeof(int));//考虑不断的malloc也会影响效率,可以在MergeSort多一个参数,传入一个内存空间来存放临时的数据,如:MergeSort(int *pArr, int start, int end,int *pTemp),

	int i = start;
	int j = mid+1;
	int k = 0;

	while (i <= mid && j <= end)
	{
		if (arr[i] < arr[j] )
		{
			pTemp[k++] = arr[i++];
		}
		else
		{
			pTemp[k++] = arr[j++];
		}
	}

	while(i <= mid)
	{
		pTemp[k++] = arr[i++];
	}

	while (j <= end)
	{
		pTemp[k++] = arr[j++];
	}
	
	k = 0;
	for (i = start; i <= end; i++)//将已经排好的Temp[0,k],放回arr[start,end]
	{
		arr[i] = pTemp[k++];
	}

	free(pTemp);
}

void MergeSort(int *pArr, int start, int end)
{
	if (start >= end)
	{
		return;
	}
	int mid = (start + end)/2;
	MergeSort(pArr, start, mid);
	MergeSort(pArr, mid+1, end);
	Merge(pArr, start, mid, end);
}

b)Python实现

def Merge(arr, start, mid, end):
	list = []
	i = start;
	j = mid+1;
	k = 0;
	while i <= mid and j <= end:
		if arr[i] > arr[j]:
			list.append(arr[j]);
			j+=1
		else:
			list.append(arr[i])
			i+=1
	while i <= mid:
		list.append(arr[i])
		i+=1
	while j <= end:
		list.append(arr[j])
		j+=1
	i = start
	for j in range(0,len(list)):
		arr[i] = list[j]
		i+=1

def MergeSort(arr, start, end):
	if start < end:
		mid = (start + end)/2
		MergeSort(arr, start, mid)
		MergeSort(arr, mid+1, end)
		Merge(arr, start, mid, end)
		
if __name__ =="__main__":
	arr = [4,3,3,1,2];
	MergeSort(arr,0,4);
	print arr;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值