以下为你提供几种经典 Python 算法的详细实现,每个代码示例行数均超过五十行,包含注释和解释,帮助你理解算法的原理和实现过程。

1. 快速排序算法

快速排序是一种高效的排序算法,采用分治法的思想。它选择一个基准元素,将数组分为两部分,使得左边部分的所有元素都小于基准元素,右边部分的所有元素都大于基准元素,然后递归地对左右两部分进行排序。

def quick_sort(arr):
    """
    快速排序函数
    :param arr: 待排序的数组
    :return: 排序好的数组
    """
    if len(arr) <= 1:
        return arr
    else:
        # 选择第一个元素作为基准
        pivot = arr[0]
        # 小于基准的元素列表
        left = []
        # 大于基准的元素列表
        right = []
        for num in arr[1:]:
            if num <= pivot:
                left.append(num)
            else:
                right.append(num)
        # 递归地对左右两部分进行排序,并合并结果
        return quick_sort(left) + [pivot] + quick_sort(right)


def partition(arr, low, high):
    """
    分区函数,用于将数组分为两部分
    :param arr: 待分区的数组
    :param low: 数组的起始索引
    :param high: 数组的结束索引
    :return: 基准元素的最终位置
    """
    # 选择最后一个元素作为基准
    pivot = arr[high]
    i = low - 1
    for j in range(low, high):
        if arr[j] <= pivot:
            i = i + 1
            # 交换元素
            arr[i], arr[j] = arr[j], arr[i]
    # 将基准元素放到正确的位置
    arr[i + 1], arr[high] = arr[high], arr[i + 1]
    return i + 1


def quick_sort_in_place(arr, low, high):
    """
    原地快速排序函数
    :param arr: 待排序的数组
    :param low: 数组的起始索引
    :param high: 数组的结束索引
    """
    if low < high:
        # 分区操作,得到基准元素的最终位置
        pi = partition(arr, low, high)
        # 递归地对基准元素左边的部分进行排序
        quick_sort_in_place(arr, low, pi - 1)
        # 递归地对基准元素右边的部分进行排序
        quick_sort_in_place(arr, pi + 1, high)


# 测试快速排序
if __name__ == "__main__":
    # 待排序的数组
    arr = [3, 6, 8, 10, 1, 2, 1]
    print("原始数组:", arr)
    # 使用非原地快速排序
    sorted_arr = quick_sort(arr.copy())
    print("非原地快速排序结果:", sorted_arr)
    # 使用原地快速排序
    quick_sort_in_place(arr, 0, len(arr) - 1)
    print("原地快速排序结果:", arr)


2. 深度优先搜索(DFS)算法

深度优先搜索是一种用于遍历或搜索树或图的算法。它沿着树的深度遍历树的节点,尽可能深地搜索树的分支。当节点 v 的所在边都己被探寻过,搜索将回溯到发现节点 v 的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。

class Graph:
    def __init__(self, vertices):
        """
        初始化图
        :param vertices: 图的顶点数量
        """
        # 顶点数量
        self.V = vertices
        # 邻接表,用于存储图的边
        self.graph = [[] for _ in range(vertices)]

    def add_edge(self, u, v):
        """
        添加边到图中
        :param u: 边的起始顶点
        :param v: 边的结束顶点
        """
        # 无向图,添加双向边
        self.graph[u].append(v)
        self.graph[v].append(u)

    def dfs_util(self, v, visited):
        """
        深度优先搜索的辅助函数
        :param v: 当前访问的顶点
        :param visited: 记录顶点是否被访问过的列表
        """
        # 标记当前顶点为已访问
        visited[v] = True
        print(v, end=' ')
        # 递归访问所有相邻的未访问顶点
        for neighbor in self.graph[v]:
            if not visited[neighbor]:
                self.dfs_util(neighbor, visited)

    def dfs(self, start):
        """
        深度优先搜索主函数
        :param start: 起始顶点
        """
        # 初始化访问标记列表
        visited = [False] * self.V
        print(f"从顶点 {start} 开始的深度优先搜索结果:")
        self.dfs_util(start, visited)


# 测试深度优先搜索
if __name__ == "__main__":
    # 创建一个包含 5 个顶点的图
    g = Graph(5)
    # 添加边
    g.add_edge(0, 1)
    g.add_edge(0, 2)
    g.add_edge(1, 2)
    g.add_edge(2, 3)
    g.add_edge(3, 4)
    # 从顶点 0 开始进行深度优先搜索
    g.dfs(0)
    print()


3. 迪杰斯特拉(Dijkstra)最短路径算法

迪杰斯特拉算法用于计算带权有向图中单个源节点到所有其他节点的最短路径。它采用贪心策略,每次选择距离源节点最近且未被处理的节点,并更新其相邻节点的距离。

import sys


class Graph:
    def __init__(self, vertices):
        """
        初始化图
        :param vertices: 图的顶点数量
        """
        # 顶点数量
        self.V = vertices
        # 邻接矩阵,用于存储图的边的权重
        self.graph = [[0 for _ in range(vertices)] for _ in range(vertices)]

    def min_distance(self, dist, spt_set):
        """
        找到距离源节点最近且未被处理的节点
        :param dist: 存储每个节点到源节点的最短距离
        :param spt_set: 记录节点是否已被处理的列表
        :return: 距离源节点最近且未被处理的节点的索引
        """
        min_dist = sys.maxsize
        min_index = -1
        for v in range(self.V):
            if dist[v] < min_dist and not spt_set[v]:
                min_dist = dist[v]
                min_index = v
        return min_index

    def dijkstra(self, src):
        """
        迪杰斯特拉算法主函数
        :param src: 源节点
        """
        # 存储每个节点到源节点的最短距离
        dist = [sys.maxsize] * self.V
        # 源节点到自身的距离为 0
        dist[src] = 0
        # 记录节点是否已被处理的列表
        spt_set = [False] * self.V

        for _ in range(self.V):
            # 找到距离源节点最近且未被处理的节点
            u = self.min_distance(dist, spt_set)
            # 标记该节点为已处理
            spt_set[u] = True
            # 更新该节点相邻节点的距离
            for v in range(self.V):
                if self.graph[u][v] > 0 and not spt_set[v] and dist[u] != sys.maxsize and dist[u] + self.graph[u][v] < dist[v]:
                    dist[v] = dist[u] + self.graph[u][v]

        # 输出每个节点到源节点的最短距离
        print("顶点 \t 距离源节点的最短距离")
        for node in range(self.V):
            print(node, "\t\t", dist[node])


# 测试迪杰斯特拉算法
if __name__ == "__main__":
    # 创建一个包含 9 个顶点的图
    g = Graph(9)
    # 邻接矩阵,表示图的边的权重
    g.graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],
               [4, 0, 8, 0, 0, 0, 0, 11, 0],
               [0, 8, 0, 7, 0, 4, 0, 0, 2],
               [0, 0, 7, 0, 9, 14, 0, 0, 0],
               [0, 0, 0, 9, 0, 10, 0, 0, 0],
               [0, 0, 4, 14, 10, 0, 2, 0, 0],
               [0, 0, 0, 0, 0, 2, 0, 1, 6],
               [8, 11, 0, 0, 0, 0, 1, 0, 7],
               [0, 0, 2, 0, 0, 0, 6, 7, 0]]
    # 从顶点 0 开始计算最短路径
    g.dijkstra(0)


这些算法实现不仅包含了核心逻辑,还有详细的注释和测试代码,有助于你深入理解算法的原理和应用。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐