返回

算法的海洋,等你来探索!10种常见算法让你从此掌握算法之美!

后端

深入探索十大流行算法

在计算机科学领域,算法是解决问题的一组明确定义的指令。高效且有效的算法对于确保现代技术平稳运行至关重要。以下是 10 种常见的算法,深入了解它们的基本原理:

1. 二分查找算法

想象一下一个图书馆,书籍按字母顺序排列在书架上。二分查找算法就像一位高效的图书管理员,它可以通过将书籍堆分成两半、与中间书籍进行比较,然后专注于正确的一半来快速找到你想要的书。

代码示例:

def binary_search(arr, target):
    low = 0
    high = len(arr) - 1

    while low <= high:
        mid = (low + high) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            low = mid + 1
        else:
            high = mid - 1

    return -1

2. 分治算法

想象一下一个复杂的问题,就像一块巨大的拼图。分治算法将这个难题分解成一系列较小的子问题,然后逐个解决它们。通过这种方式,整个问题可以像完成拼图一样一步步解决。

3. 动态规划算法

动态规划算法最适合解决涉及优化和重复子问题的难题。它将大问题分解成一系列重叠的小问题,逐一解决它们,并将结果存储起来。当需要同一子问题的解时,它可以从存储中直接检索,从而提高效率。

4. KMP 算法

在浩瀚的文字海洋中寻找一个特定的模式字符串?KMP 算法就像一位熟练的探测器,它预先处理模式字符串,然后使用该信息在给定的文本中快速匹配模式。

代码示例:

def kmp_search(text, pattern):
    n = len(text)
    m = len(pattern)

    # Preprocess the pattern
    lps = [0] * m
    j = 0

    # Compute the longest proper prefix suffix for each pattern character
    for i in range(1, m):
        while j > 0 and pattern[i] != pattern[j]:
            j = lps[j - 1]

        if pattern[i] == pattern[j]:
            j += 1
            lps[i] = j

    # Match the pattern in the text
    i = j = 0
    while i < n:
        if pattern[j] == text[i]:
            i += 1
            j += 1

        if j == m:
            return i - j

        elif i < n and pattern[j] != text[i]:
            if j != 0:
                j = lps[j - 1]
            else:
                i += 1

    return -1

5. 贪心算法

贪心算法就像一位脚踏实地的冒险家,它在每一个步骤中都做出看似最好的局部决策。它的目标是在每一步都尽可能地优化局部情况,期望最终获得全局最优解。

代码示例:

def greedy_scheduling(jobs):
    # Sort the jobs by their finish time
    jobs.sort(key=lambda job: job.finish_time)

    # Initialize the selected jobs
    selected_jobs = []

    # Iterate over the jobs
    for job in jobs:
        # Check if the job overlaps with any selected job
        overlaps = False
        for selected_job in selected_jobs:
            if job.start_time < selected_job.finish_time:
                overlaps = True
                break

        # If the job does not overlap, add it to the selected jobs
        if not overlaps:
            selected_jobs.append(job)

    return selected_jobs

6. 普里姆算法

普里姆算法是一名聪明的建筑师,它在构建一棵最低成本的生成树时非常出色。它从一个顶点开始,逐步添加具有最小权重的边,直到所有顶点都被连接起来,形成一棵树。

代码示例:

def prim_algorithm(graph):
    # Initialize the visited vertices
    visited = set()

    # Initialize the minimum spanning tree
    mst = set()

    # Initialize the total weight of the MST
    total_weight = 0

    # Iterate over the vertices
    for vertex in graph.vertices:
        # If the vertex has not been visited, add it to the MST
        if vertex not in visited:
            visited.add(vertex)
            mst.add(vertex)

            # Iterate over the edges of the vertex
            for edge in graph.edges[vertex]:
                # If the edge connects to an unvisited vertex, add it to the MST
                if edge.destination not in visited:
                    total_weight += edge.weight
                    mst.add(edge)

    return mst, total_weight

7. 克鲁斯卡尔算法

克鲁斯卡尔算法也是一位杰出的建筑师,但它在构建最低成本的生成树时采取了一种不同的方法。它从所有边开始,然后逐步添加不形成环的最小权重边,直到所有顶点都被连接起来。

代码示例:

def kruskal_algorithm(graph):
    # Initialize the disjoint sets
    disjoint_sets = DisjointSets()

    # Initialize the minimum spanning tree
    mst = set()

    # Initialize the total weight of the MST
    total_weight = 0

    # Iterate over the edges
    for edge in graph.edges:
        # If the edge does not create a cycle, add it to the MST
        if disjoint_sets.find(edge.source) != disjoint_sets.find(edge.destination):
            total_weight += edge.weight
            mst.add(edge)
            disjoint_sets.union(edge.source, edge.destination)

    return mst, total_weight

8. 迪杰斯特拉算法

迪杰斯特拉算法是一位迷宫探索者,它能够找到从源顶点到所有其他顶点的最短路径。它使用一种称为松弛的技术,该技术逐步更新路径权重,直到找到最佳路径。

代码示例:

def dijkstra_algorithm(graph, source):
    # Initialize the distances to all vertices
    distances = {}
    for vertex in graph.vertices:
        distances[vertex] = float('infinity')
    distances[source] = 0

    # Initialize the visited vertices
    visited = set()

    # Iterate until all vertices are visited
    while len(visited) < len(graph.vertices):
        # Find the unvisited vertex with the smallest distance
        min_distance = float('infinity')
        min_vertex = None
        for vertex in graph.vertices:
            if vertex not in visited and distances[vertex] < min_distance:
                min_distance = distances[vertex]
                min_vertex = vertex

        # Visit the vertex
        visited.add(min_vertex)

        # Update the distances to the adjacent vertices
        for edge in graph.edges[min_vertex]:
            new_distance = distances[min_vertex] + edge.weight
            if new_distance < distances[edge.destination]:
                distances[edge.destination] = new_distance

    return distances

9. 弗洛伊德算法

弗洛伊德算法是一个万能的旅行者,它可以找到所有顶点对之间的最短路径。它使用动态规划技术,逐个计算最短路径,直到所有路径都已找到。

代码示例:

def floyd_warshall_algorithm(graph):
    # Initialize the distances to all vertices
    distances = {}
    for vertex in graph.vertices:
        for destination in graph.vertices:
            distances[(vertex, destination)] = float('infinity')
    for edge in graph.edges:
        distances[(edge.source, edge.destination)] = edge.weight

    # Iterate over all vertices
    for vertex in graph.vertices:
        # Iterate over all edges
        for edge in graph.edges:
            # Iterate over all vertices again
            for destination in graph.vertices:
                # Relax the edges
                new_distance = distances[(edge.source, vertex)] + distances[(vertex, destination)]
                if new_distance < distances[(edge.source, destination)]:
                    distances[(edge.source, destination)] = new_distance

    return distances

10. 马踏棋盘算法

马踏棋盘算法就像一位战略性的骑士,它试图用马走遍棋盘上的所有方格,并且只走一次。它使用回溯技术,逐个尝试不同的路径,直到找到一个可行的解。

代码示例:

def knight_tour(chessboard, start_row, start_col):
    # Define the possible moves for the knight
    moves = [(1, 2), (1