冒泡排序(Bubble Sort)¶
In [4]:
def bubble_sort(arr):
n = len(arr)
for i in range(n):
# 每一轮冒泡将最大的元素冒泡到末尾
for j in range(0, n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
bubble_sort([3, 1, 4, 5, 2])
# 时间复杂度:最好情况O(n),平均和最坏情况O(n^2)
# 空间复杂度:O(1)
>>>>[ 3 1 4 5 2 ]
[0 ]-----------------
[0 ]=================
>>>>[(3){1} 4 5 2 ]
>>>>[(1){3} 4 5 2 ]
[1 ]=================
[2 ]=================
[3 ]=================
>>>>[ 1 3 4 (5){2}]
>>>>[ 1 3 4 (2){5}]
[1 ]-----------------
[0 ]=================
[1 ]=================
[2 ]=================
>>>>[ 1 3 (4){2} 5 ]
>>>>[ 1 3 (2){4} 5 ]
[2 ]-----------------
[0 ]=================
[1 ]=================
>>>>[ 1 (3){2} 4 5 ]
>>>>[ 1 (2){3} 4 5 ]
[3 ]-----------------
[0 ]=================
[4 ]-----------------
Out[4]:
[1, 2, 3, 4, 5]
插入排序(Insertion Sort)¶
In [10]:
def insertion_sort(arr):
n = len(arr)
for i in range(1, n):
key = arr[i]
j = i - 1
# 将比key大的元素向右移动一位
while j >= 0 and arr[j] > key:
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
return arr
insertion_sort([3, 1, 4, 5, 2])
# 时间复杂度:最好情况O(n),平均和最坏情况O(n^2)
# 空间复杂度:O(1)
>>>>[ 3 1 4 5 2 ]
[1 ]=================
>>>>[{3}(1) 4 5 2 ]
[0 ]-----------------
>>>>[(3){1} 4 5 2 ]
>>>>[(3) 3 4 5 2 ]
>>>>[(1) 3 4 5 2 ]
[2 ]=================
>>>>[ 1 {3}(4) 5 2 ]
>>>>[ 1 3 (4) 5 2 ]
>>>>[ 1 3 (4) 5 2 ]
[3 ]=================
>>>>[ 1 3 {4}(5) 2 ]
>>>>[ 1 3 4 (5) 2 ]
>>>>[ 1 3 4 (5) 2 ]
[4 ]=================
>>>>[ 1 3 4 {5}(2)]
[3 ]-----------------
>>>>[ 1 3 4 (5){2}]
[2 ]-----------------
>>>>[ 1 3 (4){5} 5 ]
[1 ]-----------------
>>>>[ 1 (3){4} 4 5 ]
>>>>[ 1 (3) 3 4 5 ]
>>>>[ 1 (2) 3 4 5 ]
Out[10]:
[1, 2, 3, 4, 5]
选择排序(Selection Sort)¶
时间复杂度:最好、最坏和平均情况下均为O(n^2);空间复杂度:O(1)
In [12]:
def selection_sort(arr):
n = len(arr)
for i in range(n):
# 找到未排序部分中的最小元素的索引
min_index = i
for j in range(i+1, n):
if arr[j] < arr[min_index]:
min_index = j
# 将最小元素交换到正确的位置
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
selection_sort([3, 1, 4, 5, 2])
# 时间复杂度:最好情况、平均和最坏情况都是O(n^2)
# 空间复杂度:O(1)
>>>>[ 3 1 4 5 2 ]
[0 ]=================
[1 ]-----------------
>>>>[ 3 (1) 4 5 2 ]
[2 ]-----------------
[3 ]-----------------
[4 ]-----------------
>>>>[(3){1} 4 5 2 ]
>>>>[{1}(3) 4 5 2 ]
[1 ]=================
[2 ]-----------------
[3 ]-----------------
[4 ]-----------------
>>>>[ 1 3 4 5 (2)]
>>>>[ 1 (3) 4 5 {2}]
>>>>[ 1 {2} 4 5 (3)]
[2 ]=================
[3 ]-----------------
[4 ]-----------------
>>>>[ 1 2 4 5 (3)]
>>>>[ 1 2 (4) 5 {3}]
>>>>[ 1 2 {3} 5 (4)]
[3 ]=================
[4 ]-----------------
>>>>[ 1 2 3 5 (4)]
>>>>[ 1 2 3 (5){4}]
>>>>[ 1 2 3 {4}(5)]
[4 ]=================
>>>>[ 1 2 3 4 (5)]
>>>>[ 1 2 3 4 (5)]
Out[12]:
[1, 2, 3, 4, 5]
快速排序(QuickSort)¶
时间复杂度:最好和平均情况O(nlogn),最坏情况O(n^2) 空间复杂度:最好和平均情况O(logn),最坏情况O(n)
In [16]:
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)
arr = [3, 1, 4, 5, 2, 1]
print(quicksort(arr))
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[0]
lesser = [x for x in arr[1:] if x <= pivot]
greater = [x for x in arr[1:] if x > pivot]
return quick_sort(lesser) + [pivot] + quick_sort(greater)
print(quick_sort(arr))
===================== 555555555555555555555 >>>>[ 3 1 4 2 1 ] >>>>[ 5 ] >>>>[] ===================== 444444444444444444444 >>>>[ 3 1 2 1 ] >>>>[ 4 ] >>>>[] ===================== 222222222222222222222 >>>>[ 1 1 ] >>>>[ 2 ] >>>>[ 3 ] ===================== 111111111111111111111 >>>>[] >>>>[ 1 1 ] >>>>[] [1, 1, 2, 3, 4, 5] ********************* 333333333333333333333 >>>>[ 1 2 1 ] >>>>[ 4 5 ] 111111111111111111111 >>>>[ 1 ] >>>>[ 2 ] 444444444444444444444 >>>>[] >>>>[ 5 ] [1, 1, 2, 3, 4, 5]
归并排序(MergeSort)¶
这段代码实现了归并排序算法。首先,merge_sort函数用递归的方式将数组不断二分,直到数组长度为1或者更小。然后,调用merge函数将左右两个已排序的子数组合并成一个有序的数组。最后,使用merge_sort函数对整个数组进行排序 时间复杂度:最好、平均和最坏情况都是O(nlogn) 空间复杂度:O(n)
In [20]:
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
left_half = merge_sort(left_half)
right_half = merge_sort(right_half)
return merge(left_half, right_half)
def merge(left, right):
merged = []
left_index, right_index = 0, 0
while left_index < len(left) and right_index < len(right):
if left[left_index] <= right[right_index]:
merged.append(left[left_index])
left_index += 1
else:
merged.append(right[right_index])
right_index += 1
while left_index < len(left):
merged.append(left[left_index])
left_index += 1
while right_index < len(right):
merged.append(right[right_index])
right_index += 1
return merged
# 测试示例
arr = [3, 1, 4, 5, 2, 1]
sorted_arr = merge_sort(arr)
print(sorted_arr)
333333333333333333333 >>>>[ 3 1 4 ] 111111111111111111111 >>>>[ 3 ] >>>>[ 3 ] ********************* >>>>[ 1 4 ] 111111111111111111111 >>>>[ 1 ] >>>>[ 1 ] ********************* >>>>[ 4 ] >>>>[ 4 ] >>>>[ 1 4 ] >>>>[ 1 3 4 ] ********************* >>>>[ 5 2 1 ] 111111111111111111111 >>>>[ 5 ] >>>>[ 5 ] ********************* >>>>[ 2 1 ] 111111111111111111111 >>>>[ 2 ] >>>>[ 2 ] ********************* >>>>[ 1 ] >>>>[ 1 ] >>>>[ 1 2 ] >>>>[ 1 2 5 ] [1, 1, 2, 3, 4, 5]
堆排序(HeapSort)¶
上述代码实现了堆排序算法。首先,heapify函数用于将给定的数组调整为最大堆,即每个父节点都大于或等于其子节点。它接收三个参数:数组、数组长度和当前节点索引。在函数中,首先假设当前节点是最大值,并检查其左右子节点是否比它大,如果是,则更新最大值的索引。然后,如果最大值不是父节点,则进行交换,并递归调整子树。这样就可以保证每个子树都是最大堆。 接下来,heap_sort函数用于对整个数组进行排序。首先,通过循环从最后一个非叶子节点开始,逐个调用heapify函数构建最大堆。然后,再次通过循环,从堆中取出根节点(当前最大值)并将其移到数组末尾,然后再次调用heapify函数调整堆。重复这个过程直到整个数组有序。
In [28]:
def heapify(arr, n, i):
largest = i # 假设当前节点是最大值
left = 2 * i + 1 # 左子节点的索引
right = 2 * i + 2 # 右子节点的索引
# 检查左子节点是否大于父节点
if left < n and arr[left] > arr[largest]:
largest = left
# 检查右子节点是否大于父节点
if right < n and arr[right] > arr[largest]:
largest = right
# 如果最大值不是父节点,则进行交换,并递归调整子树
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def heap_sort(arr):
n = len(arr)
# 构建最大堆,从最后一个非叶子节点开始调整
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# 逐个从堆中取出元素,并调整堆
for i in range(n - 1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # 将当前最大值移到末尾
heapify(arr, i, 0) # 调整堆
return arr
# 测试示例
arr = [9, 5, 7, 1, 3, 8, 2, 6, 4]
sorted_arr = heap_sort(arr)
print(sorted_arr)
[3 ]=================
[3 ]-----------------
>>>>[ 9 5 7 (1) 3 8 2 6 4 ]
>>>>[ 9 5 7 1 3 8 2 (6) 4 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[ 9 5 7 (1) 3 8 2 {6} 4 ]
>>>>[ 9 5 7 {6} 3 8 2 (1) 4 ]
[7 ]-----------------
>>>>[ 9 5 7 6 3 8 2 (1) 4 ]
>>>>[ 9 5 7 6 3 8 2 (1) 4 ]
[2 ]=================
[2 ]-----------------
>>>>[ 9 5 (7) 6 3 8 2 1 4 ]
>>>>[ 9 5 7 6 3 (8) 2 1 4 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[ 9 5 (7) 6 3 {8} 2 1 4 ]
>>>>[ 9 5 {8} 6 3 (7) 2 1 4 ]
[5 ]-----------------
>>>>[ 9 5 8 6 3 (7) 2 1 4 ]
>>>>[ 9 5 8 6 3 (7) 2 1 4 ]
[1 ]=================
[1 ]-----------------
>>>>[ 9 (5) 8 6 3 7 2 1 4 ]
>>>>[ 9 5 8 (6) 3 7 2 1 4 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[ 9 (5) 8 {6} 3 7 2 1 4 ]
>>>>[ 9 {6} 8 (5) 3 7 2 1 4 ]
[3 ]-----------------
>>>>[ 9 6 8 (5) 3 7 2 1 4 ]
>>>>[ 9 6 8 (5) 3 7 2 1 4 ]
[0 ]=================
[0 ]-----------------
>>>>[(9) 6 8 5 3 7 2 1 4 ]
>>>>[(9) 6 8 5 3 7 2 1 4 ]
*********************
[8 ]=================
>>>>[(9) 6 8 5 3 7 2 1 {4}]
>>>>[{4} 6 8 5 3 7 2 1 (9)]
[0 ]-----------------
>>>>[(4) 6 8 5 3 7 2 1 9 ]
>>>>[ 4 6 (8) 5 3 7 2 1 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[(4) 6 {8} 5 3 7 2 1 9 ]
>>>>[{8} 6 (4) 5 3 7 2 1 9 ]
[2 ]-----------------
>>>>[ 8 6 (4) 5 3 7 2 1 9 ]
>>>>[ 8 6 4 5 3 (7) 2 1 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[ 8 6 (4) 5 3 {7} 2 1 9 ]
>>>>[ 8 6 {7} 5 3 (4) 2 1 9 ]
[5 ]-----------------
>>>>[ 8 6 7 5 3 (4) 2 1 9 ]
>>>>[ 8 6 7 5 3 (4) 2 1 9 ]
[7 ]=================
>>>>[(8) 6 7 5 3 4 2 {1} 9 ]
>>>>[{1} 6 7 5 3 4 2 (8) 9 ]
[0 ]-----------------
>>>>[(1) 6 7 5 3 4 2 8 9 ]
>>>>[ 1 6 (7) 5 3 4 2 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[(1) 6 {7} 5 3 4 2 8 9 ]
>>>>[{7} 6 (1) 5 3 4 2 8 9 ]
[2 ]-----------------
>>>>[ 7 6 (1) 5 3 4 2 8 9 ]
>>>>[ 7 6 1 5 3 (4) 2 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[ 7 6 (1) 5 3 {4} 2 8 9 ]
>>>>[ 7 6 {4} 5 3 (1) 2 8 9 ]
[5 ]-----------------
>>>>[ 7 6 4 5 3 (1) 2 8 9 ]
>>>>[ 7 6 4 5 3 (1) 2 8 9 ]
[6 ]=================
>>>>[(7) 6 4 5 3 1 {2} 8 9 ]
>>>>[{2} 6 4 5 3 1 (7) 8 9 ]
[0 ]-----------------
>>>>[(2) 6 4 5 3 1 7 8 9 ]
>>>>[ 2 (6) 4 5 3 1 7 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[(2){6} 4 5 3 1 7 8 9 ]
>>>>[{6}(2) 4 5 3 1 7 8 9 ]
[1 ]-----------------
>>>>[ 6 (2) 4 5 3 1 7 8 9 ]
>>>>[ 6 2 4 (5) 3 1 7 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[ 6 (2) 4 {5} 3 1 7 8 9 ]
>>>>[ 6 {5} 4 (2) 3 1 7 8 9 ]
[3 ]-----------------
>>>>[ 6 5 4 (2) 3 1 7 8 9 ]
>>>>[ 6 5 4 (2) 3 1 7 8 9 ]
[5 ]=================
>>>>[(6) 5 4 2 3 {1} 7 8 9 ]
>>>>[{1} 5 4 2 3 (6) 7 8 9 ]
[0 ]-----------------
>>>>[(1) 5 4 2 3 6 7 8 9 ]
>>>>[ 1 (5) 4 2 3 6 7 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[(1){5} 4 2 3 6 7 8 9 ]
>>>>[{5}(1) 4 2 3 6 7 8 9 ]
[1 ]-----------------
>>>>[ 5 (1) 4 2 3 6 7 8 9 ]
>>>>[ 5 1 4 2 (3) 6 7 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[ 5 (1) 4 2 {3} 6 7 8 9 ]
>>>>[ 5 {3} 4 2 (1) 6 7 8 9 ]
[4 ]-----------------
>>>>[ 5 3 4 2 (1) 6 7 8 9 ]
>>>>[ 5 3 4 2 (1) 6 7 8 9 ]
[4 ]=================
>>>>[(5) 3 4 2 {1} 6 7 8 9 ]
>>>>[{1} 3 4 2 (5) 6 7 8 9 ]
[0 ]-----------------
>>>>[(1) 3 4 2 5 6 7 8 9 ]
>>>>[ 1 3 (4) 2 5 6 7 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[(1) 3 {4} 2 5 6 7 8 9 ]
>>>>[{4} 3 (1) 2 5 6 7 8 9 ]
[2 ]-----------------
>>>>[ 4 3 (1) 2 5 6 7 8 9 ]
>>>>[ 4 3 (1) 2 5 6 7 8 9 ]
[3 ]=================
>>>>[(4) 3 1 {2} 5 6 7 8 9 ]
>>>>[{2} 3 1 (4) 5 6 7 8 9 ]
[0 ]-----------------
>>>>[(2) 3 1 4 5 6 7 8 9 ]
>>>>[ 2 (3) 1 4 5 6 7 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[(2){3} 1 4 5 6 7 8 9 ]
>>>>[{3}(2) 1 4 5 6 7 8 9 ]
[1 ]-----------------
>>>>[ 3 (2) 1 4 5 6 7 8 9 ]
>>>>[ 3 (2) 1 4 5 6 7 8 9 ]
[2 ]=================
>>>>[(3) 2 {1} 4 5 6 7 8 9 ]
>>>>[{1} 2 (3) 4 5 6 7 8 9 ]
[0 ]-----------------
>>>>[(1) 2 3 4 5 6 7 8 9 ]
>>>>[ 1 (2) 3 4 5 6 7 8 9 ]
~~~~~~~~~~~~~~~~~~~~~
>>>>[(1){2} 3 4 5 6 7 8 9 ]
>>>>[{2}(1) 3 4 5 6 7 8 9 ]
[1 ]-----------------
>>>>[ 2 (1) 3 4 5 6 7 8 9 ]
>>>>[ 2 (1) 3 4 5 6 7 8 9 ]
[1 ]=================
>>>>[(2){1} 3 4 5 6 7 8 9 ]
>>>>[{1}(2) 3 4 5 6 7 8 9 ]
[0 ]-----------------
>>>>[(1) 2 3 4 5 6 7 8 9 ]
>>>>[(1) 2 3 4 5 6 7 8 9 ]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
基数排序(Radix Sort)¶
是一种非比较排序算法,它的基本思想是将待排序的数据按照位数分组,然后对每一组进行排序,最终得到有序的结果。
In [45]:
def radix_sort(lst):
# 找到最长的数字长度
max_len = max(len(x) for x in lst)
print("找到最大值,确定排序位数", max_len)
# 从个位开始,逐位进行排序
for i in range(max_len):
print(f"对第{i+1}位进行排序")
# 将数据按照当前位数分组,考虑数字长度不足的情况
groups = [[] for _ in range(10)]
for num in lst:
# 处理位数不足的情况,短的数字在高位视为0
if len(num) - i - 1 >= 0:
digit = num[-(i + 1)]
else:
digit = '0'
print("当前数", num, "当前位", digit)
groups[int(digit)].append(num)
print(groups)
# 重新组合列表
lst = [num for group in groups for num in group]
return lst
lst = ['13', '431','6', '723', '555', '281']
sorted_lst = radix_sort(lst)
print(sorted_lst)
找到最大值,确定排序位数 3 对第1位进行排序 当前数 13 当前位 3 [[], [], [], ['13'], [], [], [], [], [], []] 当前数 431 当前位 1 [[], ['431'], [], ['13'], [], [], [], [], [], []] 当前数 6 当前位 6 [[], ['431'], [], ['13'], [], [], ['6'], [], [], []] 当前数 723 当前位 3 [[], ['431'], [], ['13', '723'], [], [], ['6'], [], [], []] 当前数 555 当前位 5 [[], ['431'], [], ['13', '723'], [], ['555'], ['6'], [], [], []] 当前数 281 当前位 1 [[], ['431', '281'], [], ['13', '723'], [], ['555'], ['6'], [], [], []] 对第2位进行排序 当前数 431 当前位 3 [[], [], [], ['431'], [], [], [], [], [], []] 当前数 281 当前位 8 [[], [], [], ['431'], [], [], [], [], ['281'], []] 当前数 13 当前位 1 [[], ['13'], [], ['431'], [], [], [], [], ['281'], []] 当前数 723 当前位 2 [[], ['13'], ['723'], ['431'], [], [], [], [], ['281'], []] 当前数 555 当前位 5 [[], ['13'], ['723'], ['431'], [], ['555'], [], [], ['281'], []] 当前数 6 当前位 0 [['6'], ['13'], ['723'], ['431'], [], ['555'], [], [], ['281'], []] 对第3位进行排序 当前数 6 当前位 0 [['6'], [], [], [], [], [], [], [], [], []] 当前数 13 当前位 0 [['6', '13'], [], [], [], [], [], [], [], [], []] 当前数 723 当前位 7 [['6', '13'], [], [], [], [], [], [], ['723'], [], []] 当前数 431 当前位 4 [['6', '13'], [], [], [], ['431'], [], [], ['723'], [], []] 当前数 555 当前位 5 [['6', '13'], [], [], [], ['431'], ['555'], [], ['723'], [], []] 当前数 281 当前位 2 [['6', '13'], [], ['281'], [], ['431'], ['555'], [], ['723'], [], []] ['6', '13', '281', '431', '555', '723']
In [ ]: