各类排序算法
leetcode题目
各类排序算法
快速排序
复杂度最好为 nlogn ,最差为n^2
如果pivot取最左边的值,while循环一定要从右边开始判断
def quick_sort(input, start, end):if start >= end:returnpivot = input[start]left = startright = endwhile left < right:# print(1, input, left, right, pivot)while left < right and input[right] >= pivot:right -= 1input[left] = input[right]while left < right and input[left] <= pivot:left += 1input[right] = input[left]# print(2, input, left, right, pivot)input[right] = pivotquick_sort(input, start, right - 1)quick_sort(input, right + 1, end)input = [2, 0, 6, 12, 1, 3]
quick_sort(input, 0, len(input) - 1)
print(input)
参考链接
归并排序
复杂度为nlogn
先拆分再合并,先拆到最小,所以先递归(与快速排序不同,快排是先从最大的数组入手,再慢慢对子区间排序)
input = [2, 0, 6, 12, 1, 3]def merge_sort(input):if len(input) <= 1:return inputmid = len(input) // 2left = merge_sort(input[:mid])right = merge_sort(input[mid:])result = []i = j = 0while i<len(left) and j<len(right):if left[i] <= right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1if i == len(left):result.extend(right[j:])else:result.extend(left[i:])return resultmerge_sort(input)
参考链接
堆排序
复杂度 nlogn
参考链接
堆排序中的 “大根堆” 是逻辑上的二叉树(满足父节点大于子节点的性质),但物理上通过数组存储,依赖索引公式隐式表示父子关系,而非显式构造二叉树数据结构。这种设计是堆排序高效性的关键原因之一。
def heap_adjust(arr, start, end):"""调整堆,使以start为根的子树成为大根堆"""tmp = arr[start]i = 2 * start + 1 # 左孩子索引while i <= end:# 如果有右孩子且左孩子小于右孩子,选择右孩子if i < end and arr[i] < arr[i + 1]:i += 1# 如果子节点大于父节点,将子节点值赋给父节点if arr[i] > tmp:arr[start] = arr[i]start = ii = 2 * start + 1 # 继续向下调整else:break # 不需要调整,直接退出arr[start] = tmp # 将 tmp 值放到最终位置def heap_sort(arr):"""堆排序主函数"""length = len(arr)if length <= 1:return# 构建初始化大根堆## 从最后一个非叶子节点开始,向上遍历并调整所有节点,使其成为大根堆for i in range((length - 2) // 2, -1, -1):heap_adjust(arr, i, length - 1)print(arr)# 进行n-1次排序for i in range(length - 1):# 交换根节点和最后一个元素arr[0], arr[length - 1 - i] = arr[length - 1 - i], arr[0]# 调整剩余元素为大根堆heap_adjust(arr, 0, length - 1 - i - 1)print(i, arr)if __name__ == "__main__":arr = [9, 5, 6, 3, 5, 3, 1, 0, 96, 66]heap_sort(arr)print("排序后为:", arr)
直接选择排序
每次找到一个最小的数,交换它和最前面数的位置
复杂度n^2
# ms 直接选择排序
input = [2, 0, 6, 12, 1, 3]for i in range(len(input)):index = input.index(min(input[i:]))input[i], input[index] = input[index], input[i]
print(input)
直接插入排序
把当前遍历到的数依次插到前面的对应位置上
复杂度n^2
input = [2, 0, 6, 12, 1, 3]def insertSort(input):for i in range(1, len(input)):for j in range(i, 0, -1):if input[j] < input[j - 1]:input[j], input[j - 1] = input[j - 1], input[j]return inputinsertSort(input)
我的改进版-250806
input = [2, 0, 6, 12, 1, 3]def insertSort(input):for i in range(1, len(input)):tmp = input[i]for j in range(i, -1, -1):if tmp < input[j-1]:input[j] = input[j-1]else:input[j] = tmpbreakinput[j] = tmpreturn inputinsertSort(input)
冒泡排序
依次判断相邻的两个数,把大的放在后面,最后把最大的依次放到后面,每次遍历都会把最大的一个放到后面
复杂度n^2
input = [2, 0, 6, 12, 1, 3]def BubbleSort(input):for i in range(len(input)):for j in range(len(input) - i -1):if input[j] > input[j + 1]:input[j], input[j + 1] = input[j + 1], input[j]return inputBubbleSort(input)