![](https://img2022.cnblogs.com/blog/2727434/202210/2727434-20221029170858424-64911719.png)
由于python中关于递归有些踩坑,所以不搞对数器,就贴上单个例子验证正确的代码
视频笔记戳这里
1. 归并排序
#归并排序-递归
class solution():
def mergeSort(self, array):
"""
归并排序
:param array: List[int]
:return: None
"""
self.process(array, 0, len(array)-1)
def process(self, array, left, right):
"""
递归过程
:param array: List[int]
:param left: int
:param right: int
:return: None
"""
if left == right: return
mid = left + (right-left)>>1
self.process(array, left, mid)
self.process(array, mid+1, right)
self.merge(array, left, mid, right)
def merge(self, array, left, mid, right):
#整一个辅助空间,存放已经排好序的部分
help = []
#比较
i = left
j = mid+1
while i <= mid and j <= right:
#判断
if array[i] <= array[j]:
help.append(array[i])
i += 1
else:
help.append(array[j])
j += 1
#谁还剩,就都copy到help中
while i <= mid:
help.append(array[i])
i += 1
while j <= right:
help.append(array[j])
j += 1
#将help中的排好序的数再copy回array中
for i in range(len(help)):
array[left+i] = help[i]
2.归并排序扩展-小和问题
# 归并排序扩展
# 小和问题
class solution():
def lowerSum(self, array):
"""
求数组的array的小和
:param array: List[int]
:return: int
"""
if len(array) < 2:
return 0
return self.process(array, 0, len(array)-1)
def process(self, array, left, right):
"""
递归过程
:param array: List[int]
:param left: int
:param right: int
:return: int
"""
if left == right:
return 0
mid = left + (right-left)>>1
return self.process(array, left, mid)+self.process(array, mid+1, right)+self.merge(array, left, mid, right)
def merge(self, array, left, mid, right):
"""
将排好序且求出小和的左右两个部分整合
:param array: List[int]
:param left: int
:param mid: int
:param right: int
:return: int
"""
help = []
sum = 0
i = left
j = mid + 1
while i <= mid and j <= right:
if array[i] < array[j]:
sum += array[i]*(right-j+1)
help.append(array[i])
i += 1
else:
help.append(array[j])
j += 1
while i <= mid:
help.append(array[i])
i += 1
while j <= right:
help.append(array[j])
j += 1
for i in range(len(help)):
array[left+i] = help[i]
return sum
3.递归-快排
递归方法的快排--真的不适合,查看代码点击这里python
# 递归--快排
import random
class solution():
def quikSort(self, array):
"""
用递归和荷兰国旗思想实现的快排
:param array: List[int]
:return: None
"""
self.process(array, 0, len(array)-1)
def process(self, array, left, right):
"""
递归过程
:param array: List[int]
:param left: int
:param right: int
:return: None
"""
if left < right:
pick = random.randint(0, len(array) - 1)
array[pick], array[-1] = array[-1], array[pick]
p = self.partition(array, left, right)
self.process(array, left, p[0])
self.process(array, p[1], right)
def partition(self, array, left, right):
"""
荷兰国旗思想
:param array: List[int]
:param left: int
:param right: int
:return: tmp:List[int]
"""
i = left-1
j = right+1
now = i+1
one = array[right]
while now < j :
if array[now] < one:
array[now], array[i+1] = array[i+1], array[now]
now += 1
i += 1
elif array[now] == one:
now += 1
else:
array[now], array[j-1] = array[j-1], array[now]
j -= 1
return [i, j]
4.堆排序
class heap():
def swap(self, arr, idx1, idx2):
"""
将数组arr的两个位置为idx1和idx2的数交换
:param arr: List[int]
:param idx1: int
:param idx2: int
:return: None
"""
arr[idx1], arr[idx2] = arr[idx2], arr[idx1]
def heapInsert(self, arr, idx):
"""
以大根堆为例
当前数在数组arr的idx位置,将当前状态恢复成原本大根堆状态
:param arr: List[int]
:param idx: int
:return: None
"""
dad_idx = int((idx-1)/2)
while arr[idx] > arr[dad_idx]:
self.swap(arr, idx, dad_idx)
idx = dad_idx
dad_idx = int((idx-1)/2)
def heapify(self, arr, idx, heapsize): #heapsize便于找到堆的最后一个数
"""
当前数在数组arr的idx位置
此函数实现向下调整,以保持大根堆结构
:param arr:List[int]
:param idx:int
:param heapsize:int 当前堆的size
:return:None
"""
left = 2 * idx + 1
while(left < heapsize):
larger = left+1 if (left+1 < heapsize and arr[left] < arr[left+1]) else left
if arr[idx] > arr[larger]:
break
else:
self.swap(arr, idx, larger)
idx = larger
left = 2 * idx + 1
def heapSort(self, arr):
"""
堆排序
:param arr: List[int]
:return: None
"""
if len(arr) < 2: return
for i in range(len(arr)):
self.heapInsert(arr, i)
heapsize = len(arr)
self.swap(arr, 0, heapsize - 1)
heapsize -= 1
while heapsize > 0:
self.heapify(arr, 0, heapsize)
self.swap(arr, 0, heapsize - 1)
heapsize -= 1
4.堆结构的应用
def sortedArrDistanceLessK(self, arr, k):
"""
已知一个几乎有序的数组arr
几乎有序是指:如果把数组排好序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。
此方法用于对这个数组进行排序。
默认小根堆
:param arr: List[int]
:param k: int
:return: None
"""
heap = []
for i in range(min(len(arr), k)):
hp.heappush(heap, arr[i]) # import heapq as hp
j = 0
while i < len(arr)-1:
arr[j] = hp.heappop(heap)
hp.heappush(heap, arr[i])
j += 1
i += 1
while len(heap) != 0:
arr[j] = hp.heappop(heap)
j += 1