算法-排序

1、插入排序:

A=[1,4,7,9,10,8,12]
# j 表示现在待插入的索引,len(A)=6,range(1,len(A))的取值为1,2,3,4,5,
# 计算复杂度时还是n次,因为最后的j加一之后才跳出循环的。
for j in range(1,len(A)):
	# i表示左边第一个比较的元素索引
        i=j-1
        # 一定要注意保存当前待插入的值,因为插入过程会覆盖掉
	key = A[j]
	while (i>-1) and (A[i]>key):
		A[i+1]=A[i]
		i=i-1
	A[i+1]=key
print(A)

复杂度(c4表示第4行代码执行一次的代价):

\small T(n)=c4*n+c6*(n-1)+c8*(n-1)+c9*\sum_{j=1}^{n-1}t_j+c10*\sum_{j=1}^{n-1}(t_j-1)+c11*\sum_{j=1}^{n-1}(t_j-1)+c12*(n-1)

2、归并排序(分治思想)

采用递归的方法,将数组一直二分,直至只剩一个数字,然后开始归并

def MergeSort(lists):
	if len(lists) <= 1:
		return lists
	num = int( len(lists) / 2 )
	left = MergeSort(lists[:num])
	right = MergeSort(lists[num:])
	return Merge(left, right)
def Merge(left,right):
	r, l=0, 0
	result=[]
	while l<len(left) and r<len(right):
		if left[l] < right[r]:
			result.append(left[l])
			l += 1
		else:
			result.append(right[r])
			r += 1
	result += list(left[l:])
	result += list(right[r:])
	return result
print MergeSort([1, 2, 3, 4, 5, 6, 7, 90, 21, 23, 45])

n为数组中数字个数,那么递归树高度为lgn,层数为lgn+1,所以总代价为cn*(lgn+1)

 

 

重点:逆序对与归并排序的关系:在归并排序合并步骤时,每移动一个右边数组R中的一个数,查看未排好序左边数组L还剩多少数,然后将其总数相加,就可以得到逆序对的数目了。(思考了一下,觉得主要是因为逆序数的数目与两个数在数组的位置有关,归并排序因为递归的原因,从小达到扩大数组规模,当右边数组中任意一个数移动时,左边数组剩几个,表明有几个数和这个数是逆序数对,以此类推。因为逆序对随着逆序对向正确方向移动一次则逆序对数目减少一次,并不是交换就可以(交换会改变别的逆序对),所以需要累加。)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值