python实现所有排序算法

人生苦短,我用python😓

python 快排(不稳定)

设置哨兵(开始为第一个元素),将大的放哨兵后面,交换a[i]和a[j],直到i > j 交换a[i]和哨兵位的元素,如图,在a[i]与哨兵交换时,可能会打乱元素稳定性,如5 3 3 4 3 8 9 10 11 这里的5和3交换时

在这里插入图片描述

def quicksort(nums,l , r):
	if l >=r: return []
	i = l 
	j = r
	while i < j:
		while i<j and nums[j]>= nums[l]:#pivot = nums[l]
			j = j-1
		while i<j and nums[i] <= nums[l]:
			i = i+1
		nums[i], nums[j] = nums[j], nums[i]
	nums[i], nums[l] = nums[l], nums[i]#这里不稳定
	quicksort(nums, l, i-1)
	quicksort(nums, i+1, r)
	return nums

if __name__ =="__main__":
	print("请输入")
	lists= list(map(int,input().split()))
	sort = quicksort(lists,0,len(lists)- 1)
	for i in sort:
		print(i,end = " ")


冒泡(稳定)

将较大的元素放在后面,相同的元素不会发生交换,冒泡是稳定的排序

def bublesort(nums):
	flag = True
	for i in range(len(nums)-1): 
		flag = False
		for j in range(len(nums)-i-1):
			if(nums[j]>nums[j+1]):
				nums[j],nums[j+1] =nums[j+1],nums[j]
                flag = True
	return nums

if __name__ =="__main__":
	print("请输入")
	lists= list(map(int,input().split()))
	sort = bublesort(lists)
	for i in sort:
		print(i,end = " ")

选择排序(不稳定)

每个位置选择当前元素最小的

def selectsort(nums):
	for i in range(len(nums)-1,0,-1):
		for j in range(i):
			if nums[j] > nums[i]:#第一个元素大于后面,交换
				nums[j],nums[i] = nums[i],nums[j]
	return nums

if __name__ =="__main__":
	print("请输入")
	lists= list(map(int,input().split()))
	sort = selectsort(lists)
	for i in sort:
		print(i,end = " ")

归并排序(稳定)

#但是程序不稳定,递归太多直接报错了
import sys
sys.setrecursionlimit(10**5)

def mergesort(nums):
	# if not nums: return []
	mid =len(nums)//2
	#分解
	l = mergesort(nums[:mid])
	r = mergesort(nums[mid:])
	#合并
	result = merge(l,r)

	return result

def merge(l, r):
	i = j = 0
	m_result = []
	while i < len(l) and j < len(r):
		if l[i] < r[j]:
			m_result.append(l[i])
			l += 1
		else:
			m_result.append(r[j])
			r += 1
	m_result.append(l[i:])
	m_result.append(r[j:])

	return m_result

插入排序(稳定)

在已经有序得小序列的基础上一次插入一个元素,想要插入的元素和已经有序的最大者开始比起,相等时,插入在相等元素的后面,不破坏其稳定性

def insertsort(nums):
	for i in range(1,len(nums)):
		for j in range(i, 0 , -1):
			if nums[j] < nums[j- 1]:
				nums[j], nums[j-1] = nums[j -1],nums[j]
	return nums

if __name__ =="__main__":
	print("请输入")
	lists= list(map(int,input().split()))
	sort = insertsort(lists)
	for i in sort:
		print(i,end = " ")

希尔排序(不稳定)

插入排序的改进,把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小, 插入排序对于有序的序列效率很高

def shellsort(nums):
    n = len(nums)
    # 初始步长
    step = n // 2
    while step > 0:
        # 按步长进行插入排序
        for i in range(step, n):
            j = i
            # 插入排序
            while j >= step and nums[j - step] > nums[j]:
                nums[j - step], nums[j] = nums[j], nums[j - step]
                j -= step
        # 得到新的步长
        step = step // 2
        
    return nums
	
if __name__ =="__main__":
	print("请输入")
	lists= list(map(int,input().split()))
	sort = shellsort(lists)
	for i in sort:
		print(i,end = " ")

堆排序

大根堆、小根堆:根节点的值最大或最小,且是完全二叉树(这里可以扩展一下二叉排序树和平衡二叉树AVL)

堆排用数组存储,是节点 i 的孩子为2 * i 和 2 * i + 1 节点,

以大根堆为例,将堆顶结点与最下最右的元素交换,然后把剩下的元素再构造出一个大根堆

def heap_sort(nums):
	i, l = 0, len(nums)
	# 构造大顶堆,从非叶子节点开始倒序遍历,因此是l//2 -1 就是最后一个非叶子节点
	for i in range(l//2-1, -1, -1): 
		build_heap(i, l-1,nums)
	# 上面的循环完成了大顶堆的构造,那么就开始把根节点跟末尾节点交换,然后重新调整大顶堆  
	for j in range(l-1, -1, -1):
		nums[0], nums[j] = nums[j], nums[0]
		build_heap(0, j-1,nums)

	return nums

def build_heap(i, l, nums): 
	"""构建大顶堆"""
	left, right = 2*i+1, 2*i+2 ## 左右子节点的下标
	large_index = i 
	if left <= l and nums[i] < nums[left]:
		large_index = left

	if right <= l and nums[left] < nums[right]:
		large_index = right

	# 通过上面跟左右节点比较后,得出三个元素之间较大的下标,如果较大下表不是父节点的下标,说明交换后需要重新调整大顶堆
	if large_index != i:
		nums[i], nums[large_index] = nums[large_index], nums[i]
		build_heap(large_index, l,nums)
	
if __name__ =="__main__":
	print("请输入")
	lists= list(map(int,input().split()))
	# solutin = solution()
	sort = heap_sort(lists)
	for i in sort:
		print(i,end = " ")

总结

稳定:冒泡排序、插入排序、归并排序和基数排序

不稳定:选择排序、快速排序、希尔排序、堆排序

盗个图
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值