排序算法
1. 九种排序算法实现
1 冒泡排序(Bubble Sort)
- 注意事项:
- 冒泡排序的平均时间复杂度为O(n**2)
- 对于一般情况,这种方法是排序时间效率最低的一种方法
- 是一种稳定排序法(元素交换是在相邻元素间进行,不会改变值相同元素的相对位置)
- 代码实现
def bubbleSort(arr):
for i in range(len(arr)):
for j in range(len(arr) - i - 1):
if arr[j] > arr[j + 1]:
arr[i], arr[j + 1] = arr[j + 1], arr[j]
return arr
2 选择排序(Selection Sort)
-
注意事项:
- 选择排序的时间复杂度为O(n**2)
- 是一种不稳定排序(由于交换方式的不同可能会改变值相同元素的相对位置)
-
代码实现
def selectionSort(arr):
for i in range(len(arr) - 1):
# 记录一下最小数的索引
min_i = i
for j in range(i+1, len(arr)):
if arr[j] < arr[min_i]:
min_i = j
# 将找到的最小数放在未排序的索引起始位置
if i != min_i:
arr[i], arr[min_i] = arr[min_i], arr[i]
return arr
3. 插入排序(Insertion Sort)
- 注意:
- 插入排序的时间复杂度为O(n**2)
- 是一种稳定排序法
- 代码实现:
def insertionSort(arr):
for i in range(1, len(arr)):
temp = arr[i]
j = i
while j > 0 and arr[j - 1] > temp:
arr[j] = arr[j - 1]
j -= 1
arr[j] = temp
return arr
4. 希尔排序(Shell Sort)
-
注意:
- 按照若干间隔进行取值划分子序列,对每个子序列进行插入排序。逐渐缩小间隔的大小从而完成排序
- 排序的总趟数为logn
- 时间复杂度在O(nlogn)和O(n**2)之间
- 是一种不稳定排序法
-
代码实现:
def shellSort(arr):
size = len(arr)
gap = size//2
while gap > 0:
for i in range(gap, size):
temp = arr[i]
j = i
while j >= gap and arr[j - gap] > temp:
arr[j] = arr[j - gap]
j-= gap
arr[j] = temp
gap = gap // 2
return arr
5. 归并排序(Merge Sort)
- 注意:
- 采用递归将序列分成两半,然后两两排序合并,最终合并为结果
- 时间复杂度为O(nlogn)
- 是一种稳定排序算法
- 代码实现:
def merge(left_arr, right_arr):
arr = []
while left_arr and right_arr:
if left_arr[0] <= right_arr[0]:
arr.append(left_arr.pop(0))
else:
arr.append(right_arr.pop(0))
while left_arr:
arr.append(left_arr.pop(0))
while right_arr:
arr.append(right_arr.pop(0))
return arr
def mergeSort(arr):
size = len(arr)
if size < 2:
return arr
mid = size // 2
left_arr, right_arr = arr[:mid], arr[mid:]
return merge(mergeSort(left_arr), mergeSort(right_arr))
6. 快速排序(Quick Sort)
- 注意:
- 思想:通过一趟排序将无序序列分为两个独立的序列。第一个序列的值均比第二个序列的值小。然后递归的排序两个子序列,以达到最终的有序序列
- 选择使用生成随机数来决定中值的取值。
- 时间复杂度为O(nlogn), 空间复杂度为O(n)
- 是一种不稳定排序法
- 代码实现
import random
def randomPartition(arr: [int], low: int, high:int):
i = random.randint(low, high)
arr[i], arr[high] = arr[high], arr[i]
return partition(arr, low, high)
def partition(arr: int, low:int, high:int):
x = arr[high]
i = low - 1
for j in range(low, high):
if arr[j] <= arr[high]:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
def quickSort(arr, low, high):
# low和high为数组的起始下标和终止下标
if low < high:
pi = randomPartition(arr, low, high)
quickSort(arr, low, pi - 1)
quickSort(arr, pi + 1, high)
7. 堆排序(Heap Sort)
- 注意:
- 思想:将数组转换为大顶堆,重复从大顶堆中取出数值最大的节点,并让剩余的堆维持大顶堆性质
- 定义:
- 大顶堆:根节点值>=子节点值
- 小顶堆:根节点值<=子节点值
- 包含内容:
- 初始堆建立方法
- 堆调整方法
- 堆排序方法
- 时间复杂度为O(nlogn), 空间复杂度为O(1)
- 调整的方式为自上向下的调整
- 是一种不稳定排序法
- 代码实现
# 1.调整为大顶堆
def heapify(arr:[int], index:</