快速排序
选定一个值作为pivot,用于比较数组中的值,比pivot小放在左边,大在右边,一般pivot选数组中间的一个数。
主要分为两部分,一部分是选取pivot值 进行比较和排序。在这一部分需要注意的是:开始时将pivot和nums【0】的值交换,便于遍历。结尾需要换回来;第二点是partition的返回值是pivot对应的下标,用于递归调用。
第二部分是递归,终止条件是quicksort的参数low=high。
class Solution:
def partition(self,nums:list[int],low:int,high:int)->int:
i = (high-low)//2+low
nums[i],nums[low]=nums[low],nums[i]
pivot=nums[low]
i,j=low,high
while i <j:
while i<j and nums[j]>=pivot:
j-=1
while i<j and nums[i]<=pivot:
i+=1
nums[i],nums[j]=nums[j],nums[i]
nums[low],nums[i]=nums[i],nums[low]
return i
def quicksort(self,nums:list[int],low:int,high:int)->list[int]:
if low<high :
pivot_i=self.partition(self,nums,low,high)
self.quicksort(self,nums,low,pivot_i-1)
self.quicksort(self,nums,pivot_i,high)
return nums
score=[4,3,76,86,42,45,9,0,1]
a=Solution
print(a.quicksort(a,score,0,len(score)-1))
堆排序:
需要先明确一下定义:
堆(Heap):一种满足以下两个条件之一的完全二叉树:
大顶堆(MaxHeap):任意节点值≥其子节点值。
小顶堆(MinHeap):任意节点值≤其子节点值。
堆结构是一棵完全二叉树,
如果某二叉树节点(非叶子节点)的下标为𝑖,那么其左孩子节点下标为2×𝑖+1,右孩子节点 下标为2×𝑖+2。
• 如果某二叉树节点(非根结点)的下标为𝑖,那么其根节点下标为⌊𝑖−1 2 ⌋(向下取整)。
关于堆排序的理解:第一步遍历一趟非叶节点保证父节点大于子节点,构建大顶堆。
第二步:交换堆顶和堆底元素,堆长度减一,重新堆化
def heapify(arr:list[int],n:int,i:int):
#传入数组arr,n为数组长度,i为当前堆化的非叶节点对应的下标
maxi=i
l=2*i+1
r=2*i+2
if l<n and arr[l]>arr[maxi]:
maxi=l
if r<n and arr[r]>arr[maxi]:
maxi=r
if maxi!=i:
arr[i],arr[maxi]=arr[maxi],arr[i]
heapify(arr,n,maxi)
def heap_sort(arr:list[int])->list[int]:
n=len(arr)
for i in range((n-2)//2,-1,-1):
heapify(arr,n,i)
for i in range(n-1,0,-1):
arr[i],arr[0]=arr[0],arr[i]
heapify(arr,i,0)
return arr
print(heap_sort([1,4,32,43,7,9,66,62,11]))
计数排序:使用count记录每个值出现的次数,进行排序,比较巧妙的是最后给结果数组赋值的写法。
for num in arr:
output[count[num - min_val] - 1] = num
count[num - min_val] -= 1
def counting_sort(arr):
if not arr: # 处理输入数组为空的情况
return []
max_val = max(arr) # 找到数组中的最大值
min_val = min(arr) # 找到数组中的最小值
range_of_elements = max_val - min_val + 1 # 计算元素范围
count = [0] * range_of_elements # 初始化计数数组,存储每个元素出现的次数
output = [0] * len(arr) # 存储排序结果的数组
# 统计每个元素出现的次数
for num in arr:
count[num - min_val] += 1
# 计算累计计数,用于确定元素在排序数组中的位置
for i in range(1, range_of_elements):
count[i] += count[i - 1]
# 将元素放到输出数组的正确位置
for num in arr:
output[count[num - min_val] - 1] = num
count[num - min_val] -= 1
return output
# 示例
if __name__ == "__main__":
arr = [4, 2, 2, 8, 3, 3, 1]
print(counting_sort(arr))
基数排序:依次从低到高对每一位遍历,进行排序。
其中的buckets 是十个数组,每个数组对应当前为0-9的位。
如果想看基数排序的具体过程可以参考这篇博客,gif很具体了:超详细八大排序+基数排序(图文并茂+动图演示+C语言代码演示)_基数排序例子-优快云博客
class Solution:
def radixSort(self,nums:list[int])->list[int]:
size=len(str(max(nums)))
#逐位遍历
for i in range(size):
buckets=[[] for _ in range(10)]
for num in nums:
buckets[num//(10**i)%10].append(num)
nums.clear()
for bucket in buckets:
for num in bucket:
nums.append(num)
return nums
a=[231,464,123,543,901,800,644,299]
b=Solution
b.radixSort(b,a)