目录
1. 常用排序算法梳理
排序算法 | 时间复杂度 | 空间复杂度 | 稳定性 | 备注 |
插入排序 | O() | - | - | - |
冒泡排序 | O() | - | - | - |
快速排序 | 最好: O(nlogn) 最差: O() | 最好: O(logn) 最差: O(n) | 不稳定 | 快速排序的不稳定性主要体现在以下几个方面: 1.分区过程:
2. 交换操作:
3.递归排序:
|
堆排序 | O(nlogn) | - | 不稳定 | 建堆 -> 堆顶堆尾元素交换重建 大顶堆: 堆顶元素最大;小顶堆: 堆顶元素最小 |
归并排序 | O(nlogn) | - | 稳定 | 归并排序(Merge Sort)本质上是一种非原地排序算法,需要额外的空间来存储临时数组。 |
2. 快速排序常规写法
def quicksort(arr, low, high):
if low < high:
pivot_index = partition(arr, low, high)
quicksort(arr, low, pivot_index - 1)
quicksort(arr, pivot_index + 1, high)
def partition(arr, low, high):
pivot = arr[high] # 选择最后一个元素作为pivot
i = low - 1 # i: 小于pivot的元素的位置
for j in range(low, high):
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i] # 交换
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
# 使用
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quicksort(arr, 0, n-1)
print("Sorted array:", arr)
3. 快速排序--力扣912
考虑快排的时间复杂度最差情况,做两点小优化
def sortArray(self, nums: List[int]) -> List[int]:
def quicksort(nums, l, r):
if l < r:
if len(set(nums[l:r+1])) == 1:
return
# t = random.randint(l, r)
t = (l + r)//2
nums[t], nums[r] = nums[r], nums[t]
pivot_idx = partition(nums, l, r)
quicksort(nums, l, pivot_idx-1)
quicksort(nums, pivot_idx+1, r)
def partition(nums, l, r):
i = l - 1 # 小于 nums[r] 的位置
for j in range(l, r):
if nums[j] < nums[r]:
i += 1
nums[i], nums[j] = nums[j], nums[i]
nums[i+1], nums[r] = nums[r], nums[i+1]
return i + 1
n = len(nums)
quicksort(nums, 0, n-1)
return nums
4. 归并排序
使用归并排序也可以通过力扣912。
def sortArray(self, nums):
def mergesort(nums):
if len(nums) <= 1:
return nums
else:
mid = len(nums) // 2
left = mergesort(nums[:mid])
right = mergesort(nums[mid:])
return merge(left, right)
def merge(left, right):
res = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]: # 保持稳定排序
res.append(left[i])
i += 1
else:
res.append(right[j])
j += 1
res += left[i:]
res += right[j:]
return res
return mergesort(nums)