算法--排序算法
选择排序
# 选择排序 # 选择排序思路: # - 每次从 [i,n-1] 区间中选择最小值,放到 i 位置上 # - i 取值为 [0,n-1],因为如果最后只有一个数,则无需查询,i 取值为 [0,n-2] 即可 def select_sort(nums: list[int]): n = len(nums) if n <= 1: return for i in range(n - 1): k = i # 用k表示最小值索引 for j in range(i + 1, n): if nums[k] > nums[j]: k = j if k != i: swap(nums, i, k) def swap(nums: list[int], i: int, j: int): temp = nums[i] nums[i] = nums[j] nums[j] = temp nums = [1,3,4,2,3,4,5,67,12,23,34] select_sort(nums) print(nums)
冒泡排序
n 长度数组 nums
思路:
第一次:在 [0, n-1] 区间内冒泡
第二次:在 [0, n-2] 区间内冒泡
.....
最后一次:在 [0, 1] 区间内冒泡
伪代码:
for k from n-1 to 1:
在 [0, k] 区间内冒泡
冒泡思路:在 [0, k] 区间内冒泡
第一次:if nums[0] > nums[1] 则交换
第一次:if nums[1] > nums[2] 则交换
。。。
最后一次:if nums[k-1] > nums[k] 则交换
伪代码:
for i from 0 to k-1:
if nums[i] > nums[i+1]
swap(nums, i, i+1)
同时:n > 1 排序才有意义
def buddle_sort(nums: list[int]): n = len(nums) for t in range(n-1, 0, -1): for i in range(0, t): if nums[i] > nums[i + 1]: swap(nums, i, i + 1) def swap(nums: list[int], i: int, j: int): temp = nums[i] nums[i] = nums[j] nums[j] = temp nums = [1,3,4,2,3,4,5,67,12,23,34] buddle_sort(nums) print(nums)
public void bubble_sort(int[] nums) { int n = nums.length; if (n <= 1) return; for (int t = n - 1; t >= 1; t--) { for (int i = 0; i <= t - 1; i++) { if (nums[i] > nums[i + 1]) { swap(nums, i, i + 1); } } } } private void swap(int[] nums, int i, int j) { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; }
插入排序:
# 插入排序(类似扑克牌) def insert_sort(nums: list[int]): n = len(nums) if n <= 1: return for k in range(1, n): base = nums[k] j = k - 1 while j >=0 and nums[j] > base: nums[j + 1] = nums[j] j = j - 1 nums[j + 1] = base
快速排序:
核心点在于寻找哨兵位,然后递归排序哨位位左侧区间和右侧区间
def quick_sort(nums: list[int]): '''快速排序''' quick_sort_helper(nums, 0, len(nums) - 1) def quick_sort_helper(nums: list[int], left: int, right: int): '''递归子方法''' if right <= left: return # 哨兵位 p = part(nums, left, right) # 递归排序哨兵左侧区间 quick_sort_helper(nums, left, p - 1) # 递归排序哨兵右侧区间 quick_sort_helper(nums, p + 1, right) def part(nums: list[int], left: int, right: int) -> int: i = left j = right while i < j: # 从右边往左找第一个小于哨兵的位置 while i < j and nums[j] >= nums[left]: j = j - 1 # 从左边往右边找第一个大于哨兵的位置 while i < j and nums[i] <= nums[left]: i = i + 1 # 交换 swap(nums, left, i) return i def swap(nums: list[int], i: int, j: int): temp = nums[i] nums[i] = nums[j] nums[j] = temp nums = [1,3,4,2,3,4,5,67,12,23,34] quick_sort(nums) print(nums)
Copilot 写的(写的清晰明了多了)
def quicksort(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quicksort(left) + middle + quicksort(right)
归并排序:
分治思想
def merge_sort(nums: list[int]): '''归并排序''' merge_sort_helper(nums, 0, len(nums) - 1) def merge_sort_helper(nums: list[int], left: int, right: int): '''递归子方法''' if right <= left: return # 区分点 mid = (left + right) // 2 # 先分 merge_sort_helper(nums, left, mid) merge_sort_helper(nums, mid + 1, right) # 后治 merge(nums, left, mid, right) def merge(nums: list[int], left: int, mid: int, right: int): '''合并''' # 临时数组 temp: list[int] = [0] * (right - left + 1) i = left j = mid + 1 p = 0 while i <= mid or j <= right: if j > right or (i <= mid and nums[i] <= nums[j]): temp[p] = nums[i] i = i + 1 else: temp[p] = nums[j] j = j + 1 p = p + 1 # 拷贝数据 for t in range(left, right + 1): nums[t] = temp[t - left] nums = [1,3,4,2,3,4,5,67,12,23,34] merge_sort(nums) print(nums)
堆排序
# 使用数组 array 来表示堆(完全二叉树)的时候 # (*)i 的父节点为 (i-1)/2 # (*)i 的子节点为 i*2+1 和 i*2+2 # 堆排序流程: # 1、建堆 # 2、将堆顶放到堆数组尾部 # 3、堆长度-1 # 4、对堆顶进行从上到下堆化操作 # 5、重复2知道堆长度为1 def heap_sort(nums: list[int]): '''建堆(大顶堆)''' n = len(nums) if n <= 1: return # 原地堆化 for i in range(1, n): sift_max_up(nums, i) print(f"建堆结果 = {nums}") # 堆顶放到末尾,依次排序 for i in range(len(nums) - 1, 0, -1): swap(nums, 0, i) sift_max_down(nums, i - 1) def sift_max_up(nums: list[int], i: int): '''从底向上堆化''' while i > 0: parent = (i - 1) // 2 if nums[i] > nums[parent]: swap(nums, i, parent) i = parent def sift_max_down(nums: list[int], end: int): '''从顶向下堆化''' i = 0 while True: p = i left = 2 * i + 1 right = 2 * i + 2 if left > end and right > end: break if left <= end: if nums[p] < nums[left]: p = left if right <= end: if nums[p] < nums[right]: p = right if p == i: break swap(nums, i, p) i = p def swap(nums: list[int], i: int, j: int): temp = nums[i] nums[i] = nums[j] nums[j] = temp nums = [1,3,4,2,3,4,5,67,12,23,34] heap_sort(nums) print(nums)
计数排序:
# 算法步骤: # (1)找出最大值Max # (2)新建Max+1长度数组temp,统计每个数a出现的次数c,temp[a] = c # (3)将统计结果回填到array def count_sort(nums: list[int]): '''计数排序''' n = len(nums) if n <= 1: return max = nums[0] for i in range(0, n): if max < nums[i]: max = nums[i] temp = [0] * (max + 1) for i in range(0, n): temp[nums[i]] = temp[nums[i]] + 1 p = 0 for i in range(0, max + 1): while temp[i] > 0: nums[p] = i p = p + 1 temp[i] = temp[i] - 1 nums = [1,3,4,2,3,4,5,67,12,23,34] count_sort(nums) print(nums)
基数排序:
def radix_sort(nums: list[int]): '''基数排序''' n = len(nums) if n <= 1: return max_num = max(nums) exp = 1 while exp <= max_num: radix_sort_digital(nums, exp) exp = exp * 10 def radix_sort_digital(nums: list[int], exp): '''按位数字排序''' temp = [0] * 10 for i in range(0, len(nums)): num = nums[i] d = get_digital(num, exp) temp[d] = temp[d] + 1 # 计算前缀和,前缀和即为元素num的最后一个下标位置 for i in range(1, 10): temp[i] = temp[i] + temp[i - 1] res = [0] * len(nums) for num in nums: d = get_digital(num, exp) p = temp[d] - 1 res[p] = num temp[d] = temp[d] - 1 for i in range(0, len(nums)): nums[i] = res[i] def get_digital(num: int, exp): return (num // exp) % 10 nums = [1,3,4,1241241431,2241241431,2,3,4,5,67,12,23,34] radix_sort(nums) print(nums)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具