- 最近在复习python呢,今年工作原因,工作换的厉害,大家是否也是一样呢。博主也是费劲脑汁····,欢迎互相讨论、学习!
不说了,上代码
代码有注释,方便复习和学习。喜欢的朋友留个关注哦。博主后续还会更新的。
numberList = [3, 10, 1, 55, 48, 18, 26, 34, 89, 55, 66, 77, 15, 29, 69, 1234]
'''
1. 冒泡排序
· 每两个相邻的元素进行比较,如果顺序不对,就进行更换,每次前后比较换一遍(从头到位比较一圈),最后的元素一定是最大的。
· 所以,每比较一遍,就要少进行比较一个元素(因为比较完一遍最后一个相对应的元素一定是最大的,以此类推···)。
'''
def bubbleSort(arr):
lens = len(arr)
for l in range(1, lens):
for j in range(0, lens - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
'''
2. 选择排序
· 每次遍历所有元素进行比较时,找到最小(大)元素,遍历完毕后将最小(大)的元素和未排序的第一个元素进行互换。
· 最后如果最小(大)元素没有变,将原地不动。
'''
def selectionSort(arr):
lens = len(arr)
for l in range(lens):
minIndex = l
for j in range(l + 1, lens):
if arr[j] < arr[minIndex]:
minIndex = j
if l != minIndex:
arr[l], arr[minIndex] = arr[minIndex], arr[l]
return arr
'''
3. 插入排序
· 工作原理,通过有序序列,再对于无序序列元素,在已排序列中扫描,找到相应位置并插入
· 获取列表长度,进行循环,获取当前元素current和上一个元素index。如果上一个元素大于(倒序是小于)当前元素,则将上一个元素向后移动一位,然后将当前元素移动到合适的位置,再将当前元素向后移动一位。
'''
def insertionSort(arr):
for l in range(len(arr)):
current = arr[l]
index = l - 1
while index >= 0 and arr[index] > current:
arr[index + 1] = arr[index]
index -= 1
arr[index + 1] = current
return arr
'''
4. 希尔排序
· 将一个原始序列,开分为多个子序列,将每一个子序列排序完毕,再合并为完全体
'''
def shellSort(arr):
import math
gap = 1
length = len(arr)
# 如果原始序列满足分块条件则进行分块
while gap < (length / 3):
gap = gap * 3 + 1
# 如果gap 大于 0 每个子块就是还没有排序完毕,一直循环
while gap > 0:
# 子块进行排序
for i in range(gap, length):
temp = arr[i]
j = i - gap
# 如果元素 j 大于临时元素 temp,就进行元素互换
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
'''
5.归并排序
· 将一个原始序列两两拆分,将拆分的两个序列传递到排序方法merge
· merge 将创建两个指针,对其两个指针进行比较,将小的元素放置到新序列中,直到取值完毕
'''
def mergeSort(arr):
import math
length = len(arr)
# 如果序列长度小于2,则排序完毕,停止递归
if length < 2:
return arr
# 创建一个相对应的列表切割数,再将其列表均分为两个,不断递归,直到原始列表被拆分完毕
middle = math.floor(length / 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
'''
6. 快速排序
'''
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
# 每次开始迭代之前不管条件成立与否都至少把一个元素(pivot)摆到当前分区最后的位置。
swap(arr, pivot, index - 1)
return index - 1
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
'''
7. 堆排序
· 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法用于升序排列
· 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法用于降序排列
'''
arrLen = 0
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:
swaps(arr, i, largest)
heapify(arr, largest)
def swaps(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def heapSort(arr):
global arrLen
arrLen = len(arr)
# 创建一个堆
buildMaxHeap(arr)
for i in range(len(arr) - 1, 0, -1):
swaps(arr, 0, i)
# 把堆的尺寸缩小1,并调用heapify
arrLen -= 1
# 把新的数组顶端数据调整到相应位置
heapify(arr, 0)
return arr
'''
8. 计数排序
· 计数排序的核心在于将输入的数据值转化为键(maxValue)存在额外开辟的数组空间([0] * maxValue)。
· 作为一种线性时间复杂度的排序,技术排序要求输入的数据必须是有确定范围的整数。
'''
def countingSort(arr, maxValue):
bucketLen = maxValue + 1
# 开辟空间
bucket = [0] * bucketLen
sortedIndex = 0
arrLength = len(arr)
for i in range(arrLength):
# 每次给输入的数据,在bucket 对应的 Index = 1
bucket[arr[i]] += 1
for j in range(bucketLen):
# 如果 bucket[index]中的元素 大于0,则将 j(bucket的对应Index)赋值给要排序的数组,排序完毕为止。
while bucket[j] > 0:
arr[sortedIndex] = j
sortedIndex += 1
bucket[j] -= 1
return arr
'''
9. 桶排序
类似于计数
· 开辟一个 arr中Max数 个桶。
· 取原始数组的每一个元素,对应到桶中的一个下标。如果有重复的,则往后添加。
'''
def bucketSort(arr):
arrLens = len(arr)
bucket = [0] * max(arr)
for i in range(arrLens):
bucket[arr[i] - 1] += 1
res = []
for i in range(len(bucket)):
if bucket[i] != 0:
res += [i + 1] * bucket[i]
return res
'''
10. 基数排序
· 有运用到桶的机制,开辟一个额外空间,然后对号入桶。
· 有区别的是这个额外空间只有9个桶,因为不管多大的数字,它的个位数都对应0-9之间
· 排序max的位数次,不断针对对应的位数进行排,删,添
'''
def radixSorting(arr):
import math
i = 0
j = len(str(max(arr)))
# 排序最大“单位数”次
while i < j:
# 每一个单位数对应一个桶(max:9个)
bucket_list = [[] for _ in range(10)]
for x in arr:
# 简单说是拿到桶的Index,其实是将arr中的元素单位从“个位”->“最大位数”的一个“单位数”。
# 也就等于是Index(Index就是桶的位置),然后在对号入座。
index = math.floor(x / (10 ** i)) % 10
bucket_list[index].append(x)
# 排序完一个单位后,清空原始列表,再进行下一个单位的排序。
arr.clear()
# 给原始列表添加每次变化后的元素
[arr.append(y) for x in bucket_list for y in x]
i += 1
return arr
if __name__ == '__main__':
print("冒泡排序:", bubbleSort(numberList))
print("选择排序:", selectionSort(numberList))
print("插入排序:", insertionSort(numberList))
print("希尔排序:", shellSort(numberList))
print("归并排序:", mergeSort(numberList))
print("快速排序:", quickSort(numberList))
print("堆排序:", heapSort(numberList))
print("计数排序:", countingSort(numberList, max(numberList)))
print("桶排序:", bucketSort(numberList))
print("基数排序:", radixSorting(numberList))
博主分享了在复习Python过程中的十大经典算法,代码附带详细注释,旨在帮助读者理解和学习。适合正在学习Python算法的开发者参考,后续还会持续更新。
650





