排序算法之python归并排序

归并排序

介绍:

    归并排序是创建在归并操作上的一种有效的排序算法,1945年由冯·诺伊曼首次提出。

思想:

归并排序的实现分为递归实现与非递归(迭代)实现。递归实现的归并排序是算法设计中分治策略的典型应用,我们将一个大问题分割成小问题分别解决,然后用所有小问题的答案来解决整个大问题。非递归(迭代)实现的归并排序首先进行是两两归并,然后四四归并,然后是八八归并,一直下去直到归并了整个数组,归并排序算法主要依赖归并(Merge)操作

代码:

#!/usr/bin/python
def MergeSort(input_list):
	
	
	def merge(input_list,left,mid,right,temp):
		#合并函数
		i = left
		j = mid+1
		k=0
		while i <= mid and j <= right:
			#将左右两个升序子序列中较小的那个元素放入临时列表temp中
			if input_list[i] <= input_list[j]:
				temp[k] = input_list[i]
				i += 1
			else:
				temp[k] = input_list[j]
				j += 1
			k += 1
		
		#将剩余子序列中的元素按序加入temp中
		while i <= mid:
			temp[k] = input_list[i]
			i += 1
			k += 1
		while j <= right:
			temp[k] = input_list[j]
			j += 1
			k +=1
		#将合并好且排好序的temp复制给input_list	
		k = 0
		while left<=right:
			input_list[left] = temp[k]
			left += 1
			k += 1
		
	def merge_sort(input_list,left,right,temp):
		#递归进行归并排序
		if left >= right:
			return 
		mid = (left+right)//2
		merge_sort(input_list,left,mid,temp)
		print("本次归并后的结果是")
		print(input_list)
		#左边子序列归并
		merge_sort(input_list,mid+1,right,temp)
		#右边子序列归并
		merge(input_list,left,mid,right,temp)
		
	
	if input_list == []:
		return []
	sorted_list = input_list
	#新建一个与input_list等空间的temp变量
	temp = [0]*len(sorted_list)
	merge_sort(sorted_list,0,len(sorted_list)-1,temp)
	return sorted_list
	
		
if __name__ == '__main__':
	input_list = [50,123,543,187,49,30,0,2,11,100]
	print("input_list:")
	print(input_list)
	sorted_list = MergeSort(input_list)
	print("sorted_list:")
	print(input_list)
	

结果:

input_list:
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 30, 0, 2, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 30, 0, 2, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 0, 30, 2, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 0, 2, 30, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 0, 2, 30, 11, 100]
sorted_list:
[0, 2, 11, 30, 49, 50, 100, 123, 187, 543]

分析:

1.算法性能

2.时间复杂度

归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是O(n*log2n)

3.空间复杂度

需要一个与待排序列等空间大小的变量,故空间复杂度为O(n)

4.算法稳定性

归并排序是一种稳定排序算法,在merge函数里有如下代码,如果碰到前部分序列里元素和后部分序列里元素相等时,先把前部分序列元素放入新序列中,故,相等元素的顺序是不发生改变的。因此是稳定的

if input_list[i] <= input_list[j]:
				temp[k] = input_list[i]
				i += 1
			else:
				temp[k] = input_list[j]
				j += 1
			k += 1

5.归并排序和堆排序、快速排序的比较

若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。

若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。

若从平均情况下的排序速度考虑,应该选择快速排序。

猜你喜欢

转载自blog.csdn.net/lerry13579/article/details/82054723