AI coding 时代,各个大厂码农面试,回归基础……
数组的排序,是个基本功,没事刷一刷;不掌握好,大概率要挂。
多路归并排序
多个排序数据,如何合并成为一个。
基于 heapq 直接在 [] 中排序
import heapq
def mulit_sort(q):
Q = []
for qq in q:
heapq.heappush(Q, [qq[0], qq, 0])
rst = []
while len(Q)>0:
v, qq, idx = heapq.heappop(Q)
rst.append(v)
if idx+1<len(qq):
heapq.heappush(Q, [qq[idx+1], qq, idx+1])
return rst
构建数据结构排序
class Node:
def __init__(self, val, qq, idx):
self.val, self.qq, self.idx = val, qq, idx
def __lt__(self, other):
return self.val < other.val
def mulit_sort(q):
h = []
rst = []
for qq in q:
heapq.heappush(h, Node(qq[0], qq, 0))
while len(h)>0:
node = heapq.heappop(h)
rst.append(node.val)
if node.idx+1<len(node.qq):
heapq.heappush(h, Node(node.qq[node.idx+1], node.qq, node.idx+1))
return rst
堆排序
这是一个比较重要的排序方法,最小堆就是这么来的,可以用于数据流中获取 top k 个
def prec_down(A, i, N):
t = A[i]
while i<N:
child = i * 2 + 1
if child>=N:
break
if child+1<N and A[child+1]>A[child]:
child += 1
if A[child]>t:
A[i] = A[child]
else:
break
i = child
A[i] = t
def heap_sort(A):
N = len(A)
for i in range(N//2, -1, -1):
prec_down(A, i, N)
for i in range(N-1, -1, -1):
A[i], A[0] = A[0], A[i]
prec_down(A, 0, i)
return A
插入排序
先把元素拿出来,往前找到合适的位置,再把元素放进去
def insert_sort(A, start, end):
for i in range(start+1, end):
t = A[i]
j = i
while j>start and A[j-1]>t:
A[j] = A[j-1]
j = j-1
A[j] = t
return A
冒泡排序
相邻交换,不断往上冒泡
def swap(A, i, j):
A[i], A[j] = A[j], A[i]
def bubble_sort(A):
N = len(A)
for i in range(N):
for j in range(N-1, i, -1):
if A[j-1]>A[j]:
swap(A, j-1, j)
return A
归并排序
创建额外的空间,两个有序的数组做归并
def merge(A, tmp, p_left, p_right, q_left, q_right):
i, j, t = p_left, q_left, p_left
while i<=p_right and j<=q_right:
if A[i]<A[j]:
tmp[t] = A[i]
i += 1
else:
tmp[t] = A[j]
j += 1
t += 1
while i<=p_right:
tmp[t] = A[i]
t += 1
i += 1
while j<=q_right:
tmp[t] = A[j]
t += 1
j += 1
t = p_left
while t<=q_right:
A[t] = tmp[t]
t += 1
return A
def m_sort(A, tmp, left, right):
if left>=right:
return
mid = (left+right) // 2
m_sort(A, tmp, left, mid)
m_sort(A, tmp, mid+1, right)
merge(A, tmp, left, mid, mid+1, right)
def merge_sort(A):
N = len(A)
m_sort(A, [0]*N, 0, N-1)
return A
快速排序
两个指针,各自往前走,跟中间值做比较,再做交换
def swap(A, i, j):
A[i], A[j] = A[j], A[i]
def get_media3(A, left, right):
mid = (left+right) // 2
if A[left]>A[mid]:
swap(A,left, mid)
if A[left]>A[right]:
swap(A, left, right)
if A[mid]>A[right]:
swap(A, mid, right)
swap(A, mid, right-1 )
return A[right-1]
def q_sort(A, left,right):
if left+3<right:
pivot = get_media3(A, left, right)
i, j = left+1, right-2
while True:
while A[i]<pivot:
i += 1
while A[j]>pivot:
j -= 1
if i<j:
swap(A, i, j)
i += 1
j -= 1
else:
break
swap(A, i, right-1)
q_sort(A, left, i-1)
q_sort(A, i+1, right)
else:
insert_sort(A, left, right+1)
def quick_sort(A):
q_sort(A, 0, len(A)-1)
return A
基排序
先把个位排好序,在此基础上,按十位、百位逐级排序
def radix_sort(A):
Q = [ [] for _ in range(10) ]
radix = 1
for d in range(3):
for a in A:
idx = a // radix % 10
Q[idx].append(a)
i = 0
for q in Q:
for v in q:
A[i] = v
i += 1
Q = [ [] for _ in range(10) ]
radix = radix * 10
return A