人生苦短,我用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 = " ")
总结
稳定:冒泡排序、插入排序、归并排序和基数排序
不稳定:选择排序、快速排序、希尔排序、堆排序
盗个图