1. 冒泡排序 (Bubble Sort)
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 # 返回排序后的数组
# 示例
arr = [64, 34, 25, 12, 22, 11, 90]
print(bubble_sort(arr))
原理解释:冒泡排序是一种简单的排序算法,通过重复地遍历要排序的列表,依次比较相邻的元素,并交换顺序错误的元素。每轮遍历后,最大的元素会“冒泡”到未排序部分的最后位置,直至整个列表有序。
2. 选择排序 (Selection Sort)
def selection_sort(arr):
for i in range(len(arr)): # 遍历数组的每一个元素
min_idx = i # 假设当前元素是最小的
for j in range(i+1, len(arr)): # 从当前元素的下一个元素开始遍历
if arr[j] < arr[min_idx]: # 如果找到更小的元素
min_idx = j # 更新最小元素的索引
arr[i], arr[min_idx] = arr[min_idx], arr[i] # 交换当前元素和找到的最小元素
return arr # 返回排序后的数组
# 示例
arr = [64, 25, 12, 22, 11]
print(selection_sort(arr))
原理解释:选择排序是一种简单直观的排序算法。每次从未排序部分找到最小的元素,并将其放到已排序部分的末尾。这个过程会重复直到所有元素都被排序。
3. 插入排序 (Insertion Sort)
def insertion_sort(arr):
for i in range(1, len(arr)): # 从第二个元素开始遍历
key = arr[i] # 将当前元素作为key
j = i-1 # 从已排序部分的最后一位开始比较
while j >= 0 and key < arr[j]: # 将比key大的元素向后移
arr[j + 1] = arr[j] # 将元素向后移一位
j -= 1 # 继续向前比较
arr[j + 1] = key # 将key插入到正确的位置
return arr # 返回排序后的数组
# 示例
arr = [12, 11, 13, 5, 6]
print(insertion_sort(arr))
原理解释:插入排序通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。反复执行,直到所有数据插入完成。
4. 归并排序 (Merge Sort)
def merge_sort(arr):
if len(arr) > 1: # 如果数组长度大于1
mid = len(arr) // 2 # 找到数组的中间位置
L = arr[:mid] # 将数组分为左半部分
R = arr[mid:] # 将数组分为右半部分
merge_sort(L) # 递归排序左半部分
merge_sort(R) # 递归排序右半部分
i = j = k = 0 # 初始化三个指针
while i < len(L) and j < len(R): # 合并左右两部分
if L[i] < R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
while i < len(L): # 将剩余元素放入数组
arr[k] = L[i]
i += 1
k += 1
while j < len(R): # 将剩余元素放入数组
arr[k] = R[j]
j += 1
k += 1
return arr # 返回排序后的数组
# 示例
arr = [12, 11, 13, 5, 6, 7]
print(merge_sort(arr))
原理解释:归并排序是一种分治算法。它将数组分成两个子数组,分别排序后再合并。这个过程通过递归进行,直到子数组长度为1,再逐步合并成完整的排序数组。
5. 快速排序 (Quick Sort)
def quick_sort(arr):
if len(arr) <= 1: # 基本情况:如果数组长度为0或1,直接返回
return arr
else:
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 quick_sort(left) + middle + quick_sort(right) # 递归排序并合并
# 示例
arr = [3, 6, 8, 10, 1, 2, 1]
print(quick_sort(arr))
原理解释:快速排序通过选择一个基准元素,将数组分为小于基准、等于基准和大于基准三个部分。递归地对小于和大于基准的部分进行排序,最后合并得到排序结果。
6. 二分查找 (Binary Search)
def binary_search(arr, x):
l = 0 # 初始化左指针
r = len(arr) - 1 # 初始化右指针
while l <= r: # 当左指针不大于右指针时
mid = l + (r - l) // 2 # 计算中间位置
if arr[mid] == x: # 如果中间元素等于目标值
return mid # 返回中间元素的索引
elif arr[mid] < x: # 如果中间元素小于目标值
l = mid + 1 # 将左指针移动到中间位置的右侧
else: # 如果中间元素大于目标值
r = mid - 1 # 将右指针移动到中间位置的左侧
return -1 # 如果未找到目标值,返回-1
# 示例
arr = [2, 3, 4, 10, 40]
x = 10
print(binary_search(arr, x))
原理解释:二分查找是一种高效的查找算法,前提是数组已排序。通过反复将查找范围减半,快速定位目标值。如果中间元素等于目标值,返回其索引;否则根据目标值与中间元素的比较结果,缩小查找范围。
7. 斐波那契数列 (Fibonacci Sequence)
def fibonacci(n):
if n <= 0: # 如果输入小于等于0,返回空列表
return []
elif n == 1: # 如果输入为1,返回[0]
return [0]
elif n == 2: # 如果输入为2,返回[0, 1]
return [0, 1]
fib_seq = [0, 1] # 初始化斐波那契数列前两个元素
for i in range(2, n): # 从第3个元素开始生成
fib_seq.append(fib_seq[i-1] + fib_seq[i-2]) # 当前元素等于前两个元素之和
return fib_seq # 返回生成的斐波那契数列
# 示例
n = 10
print(fibonacci(n))
原理解释:斐波那契数列是一种数列,其中每个数是前两个数的和。数列从0和1开始,依次生成。这个算法通过迭代生成指定长度的斐波那契数列。
好的,继续为您提供后续算法的 Python 实现及其解释:
8. 欧几里得算法 (求最大公约数) (Euclidean Algorithm for GCD)
def gcd(a, b):
while b: # 当b不为0时
a, b = b, a % b # a取b的值,b取a除以b的余数
return a # 返回a,即最大公约数
# 示例
a = 60
b = 48
print(gcd(a, b))
原理解释:欧几里得算法是一种用于计算两个整数最大公约数的高效算法。通过反复交换两个数并取余数,直到余数为0,此时的另一个数即为最大公约数。
9. 深度优先搜索 (DFS)
def dfs(graph, start, visited=None):
if visited is None: # 如果未初始化visited集合
visited = set() # 初始化visited集合
visited.add(start) # 将起始节点加入visited集合
print(start) # 打印当前访问的节点
for next in graph[start] - visited: # 遍历当前节点的所有未访问邻居
dfs(graph, next, visited) # 递归调用DFS
return visited # 返回visited集合
# 示例
graph = {'A': {'B', 'C'}, 'B': {'A', 'D', 'E'}, 'C': {'A', 'F'}, 'D': {'B'}, 'E': {'B', 'F'}, 'F': {'C', 'E'}}
dfs(graph, 'A')
原理解释:深度优先搜索是一种用于遍历或搜索图结构的算法。它从起始节点开始,沿着每条边尽可能深入,再回溯到上一个节点继续搜索未访问的邻居节点。适用于解决连通性、路径发现等问题。
10. 广度优先搜索 (BFS)
from collections import deque
def bfs(graph, start):
visited = set() # 初始化visited集合
queue = deque([start]) # 初始化队列并将起始节点入队
visited.add(start) # 将起始节点加入visited集合
while queue: # 当队列不为空时
vertex = queue.popleft() # 从队列中取出一个节点
print(vertex) # 打印当前访问的节点
for neighbor in graph[vertex]: # 遍历当前节点的所有邻居
if neighbor not in visited: # 如果邻居未被访问
visited.add(neighbor) # 将邻居加入visited集合
queue.append(neighbor) # 将邻居入队
return visited # 返回visited集合
# 示例
graph = {'A': {'B', 'C'}, 'B': {'A', 'D', 'E'}, 'C': {'A', 'F'}, 'D': {'B'}, 'E': {'B', 'F'}, 'F': {'C', 'E'}}
bfs(graph, 'A')
原理解释:广度优先搜索是一种用于遍历或搜索图结构的算法。它从起始节点开始,先访问所有相邻节点,然后依次访问这些节点的相邻节点。适用于解决最短路径、连通性等问题。
总结:
这些入门算法涵盖了排序、搜索和图遍历等基本算法,是学习算法和数据结构的重要基础。通过掌握这些算法,不仅可以提升编程能力,还能为更复杂的算法学习打下坚实的基础。
原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/78996.html