2020-2-29(51)

选择排序
核心思想:给定一个数组,如何将这个数组进行排序得到一个有序的序列。
常规的选择最小值,放置,最终有序的过程
【3,2,11,-9,0,12】
1. -9 【-9,3,2,11,0,12】
2. 0 【-9,0,3,2,11,12】
3. 。。。。。
选择排序的排序过程
【3,2,11,-9,0,12】
1. 选择数组从索引0-(length-1)中最小的元素的索引,和第一个元素(索引为0)交换位置 ------>【-9,2,11,3,0,12】
2.选择数组从索引1-(length-1)中最小的元素的索引,和第二个元素(索引为1)交换位置------>【-9,0,11,3,2,12】
3.选择数组从索引2-(length-1)中最小的元素的索引,和第三个元素(索引为2)交换位置------>【-9,0,2,3,11,12】
4。。。。
结论:
1. 选择的次数为len(arr)
2. 选择的序列是逐渐缩短的
#时间复杂度分析:
[1-n)------>n-1
[2-n]------>n-2
[3-n)------>n-3

n-1+n-2+n-3+…1------>(n2-n)/2
n-1+n-2+n-3+…1=(n2-n)/2------>O(n22)
#稳定性 [-129893,-9,2,2,12,12,0,-9,0,20]------>不稳定

#代码实现:

def selectSort(arr):
	#	1. 选择的次数为len(arr)
	#	2. 选择的序列是逐渐缩短的
	length = len(arr)
	for i in range(length):#选择多少次
		min_value_index = i#假定最小元素的索引为i
		#找数组中最小元素的索引
		for j in range(i+1,length):
			if arr[j]<arr[min_value_index]:
				min_value_index = j
		#放置到对应的位置
		arr[i],arr[min_value_index] = arr[min_value_index],arr[i]
	return arr
arr = [-9,9,2,2,12,12,0,129893,0,20]
print(selectSort(arr))

堆排序
满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树
堆的特点:
定义任意节点的索引为i
左子节点索引2i+1
右子节点的索引2
i+2
对于一个大顶堆来说最大的元素必然是堆顶的元素
堆排序的算法核心思想:
1. 建堆(保证了最大元素是堆顶)
2. 把堆顶元素和最后一个元素交换(最大的元素就是在最后一个位置了)
3.调整堆结构,使堆满足堆的条件(注意点,调整的时候不再考虑最后一个元素了)
4.调整以后,堆又满足了堆的条件
5. 此时将堆顶元素和倒数第二个元素交换。。。
6. 调整。。。。交换。。。调整。。。。交换

考虑实现过程:
1. 如何让我们的数组满足堆的定义------>解决方案:建堆
-构建堆的过程:
(1) 先从堆的最后一个非叶子节点开始,进行调整
对于一个长度为n的数组来说,映射到堆的定义上来说,最后一个非叶子节点的索引为n//2-1
(2)找到第二个非叶子节点进行调整
(3) 。。。。
(4) 一直找到最后一个非叶子节点进行调整
2. 堆顶和最后一个元素进行交换(换完了以后堆的结构被破坏了,但是最后一个元素可以确定是最大的元素)
3.调整堆的过程的时候,交换位置可能导致子节点为跟的堆被破坏结构,这个时候要继续坚持以该节点为根的结构是否满足堆结构,不满足,则需要交换
4.-调整完了以后,继续换堆顶元素和倒数第二个元素的位置(此时保证了最大元素和倒数第二大的元素在最后2个位置)
-缩小堆的规模,继续调整堆
-换位置
-缩小堆的规模,继续调整堆
-换位置
-缩小堆的规模,继续调整堆
-换位置
-缩小堆的规模,继续调整堆
-换位置。。。。

#代码实现

def heapify(arr,action_node_index,length):

	"""
	arr :传入的数组
	action_node_index:待调整的堆的节点索引
	length:是堆的规模
	"""
	left_child_index = 2*action_node_index+1
	right_child_index = 2*action_node_index+2
	max_value_index = action_node_index
	#分别和左右子节点进行比较,找到最大的值对应的index
	if left_child_index<length and arr[left_child_index]>arr[max_value_index]:
		max_value_index = left_child_index
	if right_child_index<length and arr[right_child_index]>arr[max_value_index]:
		max_value_index = right_child_index
	#如果最大值的索引发生了变化
	if max_value_index!=action_node_index:
		arr[action_node_index],arr[max_value_index]=arr[max_value_index],arr[action_node_index]
		#因为位置交换可能导致被交换的地方的堆不满足堆的结构,因此继续调整基于该节点为根的堆结构
		heapify(arr,max_value_index,length)
def buildheapify(arr):
	#先从堆的最后一个非叶子节点开始,进行调整
	for i in range(len(arr)//2-1,-1,-1):
		heapify(arr,i,len(arr))
	return arr

def heapifySort(arr):
	length = len(arr)
	buildheapify(arr)
	for i in range(length):
		#做交换
		arr[0],arr[length-1-i] = arr[length-1-i],arr[0]
		#调整堆结构
		heapify(arr,0,length-1-i)
	return arr
#arr = [1,39,21,1,12,2,0]
arr = [-129893,-9,2,2,12,12,0,-9,0,20]
print(heapifySort(arr))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值