
本文介绍了Python中常见的排序算法及其实现,包括冒泡排序(稳定,O(n²))、选择排序(不稳定,O(n²))、插入排序(稳定,O(n²)最好O(n))、希尔排序(不稳定,O(nlogn))、归并排序(稳定,O(nlogn))、快速排序(不稳定,平均O(nlogn))、堆排序(不稳定,O(nlogn))、计数排序(稳定,O(n+k))、桶排序(稳定,O(n+k))和基数排序(稳定,O(nk))。每种算法都给出了核心原理、时间复杂度和Python实现代码,并指出适用场景,如快速排序适合大数据量,计数排序适合范围固定的整数。
-
冒泡排序
-
原理:重复比较相邻元素,将较大的元素逐渐"冒泡"到数组末尾。
-
时间复杂度:平均和最坏情况均为O(n2)O(n2),稳定。
-
代码示例 :
def bubblesort(arr): for i in range(1, len(arr)): for j in range(0, len(arr)-i): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] return arr
-
-
选择排序
-
原理:每次从未排序部分选择最小元素,与未排序部分的第一个元素交换。
-
时间复杂度:O(n2)O(n2),不稳定。
-
代码示例 :
def selectionsort(arr): for i in range(len(arr)-1): minindex = i for j in range(i+1, len(arr)): if arr[j] < arr[minindex]: minindex = j if i != minindex: arr[i], arr[minindex] = arr[minindex], arr[i] return arr
-
-
插入排序
-
原理:将元素逐个插入到已排序序列的合适位置。
-
时间复杂度:平均O(n2)O(n2),最好情况O(n)O(n),稳定。
-
代码示例 :
def insertionsort(arr): for i in range(len(arr)): preindex = i-1 current = arr[i] while preindex >= 0 and arr[preindex] > current: arr[preindex+1] = arr[preindex] preindex -= 1 arr[preindex+1] = current return arr
-
-
希尔排序
-
原理:基于插入排序的改进,通过分组插入减少数据移动次数。
-
时间复杂度:平均O(nlogn)O(nlogn),不稳定。
-
代码示例 :
def shellsort(arr): import math gap = 1 while gap < len(arr)/3: gap = gap*3 + 1 while gap > 0: for i in range(gap, len(arr)): temp = arr[i] j = i - gap while j >= 0 and arr[j] > temp: arr[j+gap] = arr[j] j -= gap arr[j+gap] = temp gap = math.floor(gap/3) return arr
-
-
归并排序
-
原理:采用分治法,将数组分成两半,分别排序后再合并。
-
时间复杂度:O(nlogn)O(nlogn),稳定。
-
代码示例 :
def mergesort(arr): import math if len(arr) < 2: return arr middle = math.floor(len(arr)/2) left, right = arr[0:middle], arr[middle:] return merge(mergesort(left), mergesort(right)) def merge(left, right): result = [] while left and right: if left[0] <= right[0]: result.append(left.pop(0)) else: result.append(right.pop(0)) while left: result.append(left.pop(0)) while right: result.append(right.pop(0)) return result
-
-
快速排序
-
原理:选择一个基准元素,将数组分为小于和大于基准的两部分,递归排序。
-
时间复杂度:平均O(nlogn)O(nlogn),最坏O(n2)O(n2),不稳定。
-
代码示例 :
def quicksort(arr, left=None, right=None): left = 0 if not isinstance(left, (int, float)) else left right = len(arr)-1 if not isinstance(right, (int, float)) else right if left < right: partitionindex = partition(arr, left, right) quicksort(arr, left, partitionindex-1) quicksort(arr, partitionindex+1, right) return arr def partition(arr, left, right): pivot = left index = pivot + 1 i = index while i <= right: if arr[i] < arr[pivot]: swap(arr, i, index) index += 1 i += 1 swap(arr, pivot, index-1) return index-1 def swap(arr, i, j): arr[i], arr[j] = arr[j], arr[i]
-
-
堆排序
-
原理:利用堆结构,每次取出堆顶元素构建有序序列。
-
时间复杂度:O(nlogn)O(nlogn),不稳定。
-
代码示例 :
def heapsort(arr): global arrlen arrlen = len(arr) buildmaxheap(arr) for i in range(len(arr)-1, 0, -1): swap(arr, 0, i) arrlen -= 1 heapify(arr, 0) return arr def buildmaxheap(arr): import math for i in range(math.floor(len(arr)/2), -1, -1): heapify(arr, i) def heapify(arr, i): left = 2*i + 1 right = 2*i + 2 largest = i if left < arrlen and arr[left] > arr[largest]: largest = left if right < arrlen and arr[right] > arr[largest]: largest = right if largest != i: swap(arr, i, largest) heapify(arr, largest)
-
-
计数排序
-
原理:统计元素出现次数,按顺序填充到结果数组。
-
时间复杂度:O(n+k)O(n+k),稳定。
-
代码示例 :
def countingsort(arr, maxvalue): bucketlen = maxvalue + 1 bucket = [0] * bucketlen sortedindex = 0 arrlen = len(arr) for i in range(arrlen): if not bucket[arr[i]]: bucket[arr[i]] = 0 bucket[arr[i]] += 1 for j in range(bucketlen): while bucket[j] > 0: arr[sortedindex] = j sortedindex += 1 bucket[j] -= 1 return arr
-
-
桶排序
-
原理:将数据分到不同桶中,对每个桶排序后合并。
-
时间复杂度:O(n+k)O(n+k),稳定。
-
代码示例 :
def bucket_sort(s): min_num = min(s) max_num = max(s) bucket_range = (max_num - min_num) / len(s) count_list = [[] for _ in range(len(s)+1)] for i in s: count_list[int((i - min_num) // bucket_range)].append(i) s.clear() for i in count_list: for j in sorted(i): s.append(j)
-
-
基数排序
-
原理:按数字位数从低位到高位依次排序。
-
时间复杂度:O(nk)O(nk),稳定。
-
代码示例 :
def radixsort(list): i = 0 n = 1 max_num = max(list) while max_num > 10**n: n += 1 while i < n: bucket = {} for x in range(10): bucket.setdefault(x, []) for x in list: radix = int((x / (10**i)) % 10) bucket[radix].append(x) j = 0 for k in range(10): if len(bucket[k]) != 0: for y in bucket[k]: list[j] = y j += 1 i += 1 return list
-
以上算法可根据数据特点和需求选择,如快速排序适合大数据量,计数排序适合范围固定的整数。