0
点赞
收藏
分享

微信扫一扫

pythosn实现 排序算法

新鲜小饼干 2022-03-30 阅读 3
算法python

各种排序算法

在这里插入图片描述

O(n2)

——————————————————————————————

冒泡排序,稳定排序

每一轮都要遍历所有元素,总共遍历(元素数量 - 1)轮

# 冒泡排序,最大的冒泡上去,最后元素最大

def bubble_sort1(array = []):
	for i in range(len(array) - 1):
		for j in range(len(array) - i - 1):
			if array[j] > array[j + 1]:
				temp = array[j]
				array[j] = array[j + 1]
				array[j + 1] = temp

# 冒泡优化,设置标志位
def bubble_sort2(array = []):
	for i in range(len(array) - 1):
		# 有序标记,每一轮初始值是True
		is_sorted = True
		for j in range(len(array) - i - 1):
			if array[j] > array[j + 1]:
				temp = array[j]
				array[j] = array[j + 1]
				array[j + 1] = temp
				# 有元素交换,所以是有序的,标记变为False
				is_sorted = False
	  # 如果发现标志位没有变为False,意思是没有交换,已经有序,则直接退出
		if is_sorted:
			break

# 优化3,在每一轮排序后,记录下最后一次元素交换的位置,则该位置即为无序数列的边界,再往后就是有序曲了
def bubble_sort3(array = []):
	# 记录最后一次交换的位置
	last_exchange_index = 0
	# 无序数列的边界,每次比较只需比到这里
	sort_border = len(array) - 1
	for i in range(len(array) - 1):
		# 有序标记,每一轮的初始是True
		is_sorted = True
		for j in range(sort_border):
			if array[j] > array[j + 1]:
				temp = array[j]
				array[j] = array[j + 1]
				array[j + 1] = temp
				# 已经交换,所以变为False
				is_sorted = False
				# 把无序数列的边界值更新为最后一次交换元素的位置
				last_exchange_index = j
		sort_border = last_exchange_index
		if is_sorted:
			break

my_array = list([3,5,7,2,3,44,5,0])
bubble_sort1(my_array)
print(my_array) #[0, 2, 3, 3, 5, 5, 7, 44]

选择排序

插入排序

O(nlogn)

——————————————————————————————

快速排序

找基准元素,partition
递归基准元素左边的,递归右边的

# 得到基准元素
pivot_index = partition1(start_index, end_index, array)
# 根据基准元素,分成俩部分递归排序
quick_sort(start_index, pivot_index - 1, array)
quick_sort(pivot_index + 1, end_index, array)

code

# 快排算法

# 双边循环法实现的快排
def quick_sort(start_index, end_index, array = []):
	# 递归结束的条件
	if start_index >= end_index:
		return 
	# 得到基准元素
	pivot_index = partition1(start_index, end_index, array)
	# 根据基准元素,分成俩部分递归排序
	quick_sort(start_index, pivot_index - 1, array)
	quick_sort(pivot_index + 1, end_index, array)

def partition1(start_index, end_index, array = []):
	# 取第一个位置的元素为基准元素
	pivot = array[start_index]
	left = start_index
	right = end_index
	while left != right:
		# 控制rigth 右指针进行比较并左移
		while left < right and array[right] > pivot:
			right -= 1
		# 控制left 左指针进行比较并右移
		while left < right and array[left] <= pivot:
			left += 1
		# 交换left 指针和right 指针所指向的元素
		temp = array[left]
		array[left] = array[right]
		array[right] = temp
	# pivot和指针重合点交换
	array[start_index] = array[left]
	array[left] = pivot
	return left

# 单边循环法
def partition2(start_index, end_index, array= []):
	pivot = array[start_index]
	# mark指针指向数列起始位置,这个mark指向代表小于基准元素的区域边界
	mark = start_index
	for i in range(start_index + 1, end_index + 1):
		 if array[i] < pivot:
		 	mark += 1
		 	temp = array[mark]
		 	array[mark] = array[i]
		 	array[i] = temp
	# 循环结束后,mark 和pivot 交换
	array[start_index] = array[mark]
	array[mark] = pivot
	return mark

my_array = list([3,4,14,1,5,6,7,8,-1,11])
quick_sort(0, len(my_array) - 1, my_array)

print(my_array)






归并排序

堆排序

1.把无序数组构建成最大堆
2.循环交换集合尾部元素到堆顶,并调节堆产生新的堆顶

注意,此时排序出的结果是从小到大,如果想从大到小,只需改变函数down_adjust1里面的while 循环里面的俩个if语句,使之构建的是大根堆。

"""
堆排序
1.把无序数组构建成最大堆
2.循环交换集合尾部元素到堆顶,并调节堆产生新的堆顶
"""
def heap_sort(array = []):
	# 1.把无序数组构建成最大堆
	for i in range((len(array) - 2) // 2, -1, -1):
		down_adjust1(i, len(array), array)

	# 2.循环交换集合尾部元素到堆顶,并调节堆产生新的堆顶
	for i in range(len(array) - 1, 0 ,-1):
		# 最后一个元素和第一个元素交换
		temp = array[i]
		array[i] = array[0]
		array[0] = temp
		# 下沉调整最大堆
		down_adjust1(0, i, array)

def down_adjust1(parant_index, length, array = []):
	temp = array[parant_index] # 保存栈顶元素array[0]
	child_index = 2 * parant_index + 1
	while child_index < length:
		if child_index + 1 < length and array[child_index + 1] > array[child_index]:
			child_index += 1
		if temp >= array[child_index]:
			break
		array[parant_index] = array[child_index]
		parant_index = child_index
		child_index = 2 * parant_index + 1
	array[parant_index] = temp


my_array_2 = list([3,5,6,3,2,6,77,-1,6,78])
heap_sort(my_array_2)
print(my_array_2)

计算排序,不基于比较的

“”"
1.得到数列的最大值
2.根据数列最大值确定体积数组的最大值
3.遍历数组,填充统计数组
4.遍历统计数组,输出结果
“”"
优化版:
“”"
1.得到数列的最大值和最小值,并计算出插值d
2.创建统计数组并统计对应元素个数
3.统计数组变形,后面的元素等于前面的元素之和
4.倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组
“”"
原始数列规模n,最大值和最小值差值m,
时间复杂度:O(n+m)
空间复杂度:O(m)
局限性:
1.当数列最大值和最小值差距过大时,并不适合计数排序
2.当数列不是整数时,也不适合计数排序

# 计算排序,不需要比较的排序
"""
	1.得到数列的最大值
	2.根据数列最大值确定体积数组的最大值
	3.遍历数组,填充统计数组
	4.遍历统计数组,输出结果
"""
def count_sort(arrey = []):
	# 1.得到数列的最大值
	max_value = arrey[0]
	for i in range(1, len(arrey)):
		if max_value < arrey[i]:
			max_value = arrey[i]
	# 2.根据数列最大值确定统计数组的最大值
	count_array = [0] * (max_value + 1)
	# 3.遍历数组,填充统计数组
	for i in range(0, len(arrey)):
		count_array[arrey[i]] += 1
	# 4.遍历统计数组,输出结果
	ans = []
	for i in range(0, len(count_array)):
		for j in range(0, count_array[i]):
			ans.append(i)
	print(ans)


"""
	1.得到数列的最大值和最小值,并计算出插值d
	2.创建统计数组并统计对应元素个数
	3.统计数组变形,后面的元素等于前面的元素之和	
	4.倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组
"""
def count_sort2(arrey = []):
	# 1.得到数列的最大值和最小值,并计算出插值d
	max_value = arrey[0]
	min_value = arrey[0]
	for i in range(1, len(arrey)):
		if arrey[i] > max_value:
			max_value = arrey[i]
		if arrey[i] < min_value:
			min_value = arrey[i]
	d = max_value - min_value + 1
	# 2.创建统计数组并统计对应元素个数
	count_array = [0] * d
	for i in range(0, len(arrey)):
		count_array[arrey[i] - min_value] += 1
	# 3.统计数组变形,从第二个元素开始,后面的元素等于前面的元素之和
	for i in range(1, len(count_array)):
		count_array[i] += count_array[i - 1]
	# 4.倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组
	ans = [0] * len(arrey)
	for i in range(len(arrey) - 1 , -1, -1):
		ans[count_array[arrey[i] - min_value] - 1] = arrey[i]
		count_array[arrey[i] - min_value] -= 1
	return ans

my_array = list([95,94,91,98,99,90,99,99,91,92])

print(count_sort2(my_array))

桶排序

1.得到数列的最大值和最小值,并计算出差值d
2.初始化桶
3.遍历原始数组,将每个元素放入桶中
4.对每个桶内部进行排序
5.输出全部元素

桶区间跨度:(最大值 - 最小值) / (桶的数量 - 1 )
桶的数量 = len(array)

时间复杂度 :O(n)
空间复杂度 :O(n)

# 桶排序
"""
	1.得到数列的最大值和最小值,并计算出差值d
	2.初始化桶
	3.遍历原始数组,将每个元素放入桶中
	4.对每个桶内部进行排序
	5.输出全部元素
"""

def bucket_sort(array = []):
	# 1.得到数列的最大值和最小值,并计算出差值d
	max_value = array[0]
	min_value = array[0]
	for i in range(1, len(array)):
		if array[i] > max_value:
			max_value = array[i]
		if array[i] < min_value:
			min_value = array[i]
	d = max_value - min_value
	# 2.初始化桶
	bucket_num = len(array) # 桶的数量等于数组长度
	bucket_list = []
	for i in range(0, bucket_num):
		bucket_list.append([])
	# 3.遍历原始数组,将每个元素放入桶中
	for i in range(0, len(array)):
		# 确定这个数是属于那个编号的桶
		num = int((array[i] - min_value) * (bucket_num - 1) / d)
		bucket = bucket_list[num] # 拿到大数组中的桶号
		bucket.append(array[i]) #再这个桶中添加数字
	# 4.对每个桶内部进行排序
	for i in range(0, len(bucket_list)):
		bucket_list[i].sort()
	# 5.输出全部元素
	ans = []
	# 双循环,sub_list是代表桶和上次循环的bucket 一样
	for sub_list in bucket_list:
		for i in sub_list:
			ans.append(i)
	return ans

my_list = list([4.12,0.0045,4,2.34,8.67,45.3])
print(bucket_sort(my_list))
举报

相关推荐

0 条评论