首页 > 编程语言 >探索编程世界的宝藏:程序员必掌握的20大算法

探索编程世界的宝藏:程序员必掌握的20大算法

时间:2023-08-20 11:02:31浏览次数:54  
标签:arr 20 image 编程 程序员 算法 排序 节点 def

#程序员必须掌握哪些算法?#

在这里插入图片描述

1 引言

在当今数字化时代,程序员们仍然需要拥有一把解决问题和优化代码的金钥匙。这些钥匙是算法,它们隐藏在计算机科学的宝藏中,等待着我们去发现和掌握。本篇博文将带你踏上一段引人入胜的探险之旅,揭开程序员必须掌握的20大算法的神秘面纱。从冒泡排序到深度优先搜索,我们将一起探索这些算法的原理、应用场景,为你的学习之旅增添乐趣和激励。

2 冒泡排序算法:编程世界的排序魔法

冒泡排序算法的基本思想是:将待排序的元素按照大小进行比较,较大的元素逐渐“浮”到列表的末尾,而较小的元素逐渐“沉”到列表的开头。通过多次遍历和交换操作,直到整个列表按照升序排列为止。虽然冒泡排序的性能不如一些高级排序算法,但它直观易懂,是学习排序算法的入门必备。

以下是Python代码示例,展示了冒泡排序算法的实现过程:

def bubble_sort(arr):
    n = len(arr)
    
    for i in range(n - 1):
        for j in range(0, n - i - 1):
            # 比较相邻的元素
            if arr[j] > arr[j + 1]:
                # 交换元素位置
                arr[j], arr[j + 1] = arr[j + 1], arr[j]

# 测试
arr = [64, 34, 25, 12, 22, 11, 90]
bubble_sort(arr)
print("排序结果:", arr)

通过运行以上代码,你可以看到冒泡排序算法将列表 [64, 34, 25, 12, 22, 11, 90] 按照升序排列后的结果。

冒泡排序算法或许简单,但它的思想对于理解其他高级排序算法以及算法设计的基本原理非常重要。

3 选择排序算法:排序世界的精确挑选器

选择排序算法的思想非常直观:从待排序的序列中选择最小的元素,并将其放置在序列的起始位置。然后,在剩余的未排序部分中继续选择最小的元素,不断将其放置在已排序部分的末尾。经过多次遍历和交换操作,直到整个序列按照升序排列为止。

以下是Python代码示例,展示了选择排序算法的实现过程:

def selection_sort(arr):
    n = len(arr)
    
    for i in range(n - 1):
        min_idx = i
        for j in range(i + 1, n):
            # 找到未排序部分中的最小元素的索引
            if arr[j] < arr[min_idx]:
                min_idx = j
        
        # 将最小元素与当前位置进行交换
        arr[i], arr[min_idx] = arr[min_idx], arr[i]

# 测试
arr = [64, 34, 25, 12, 22, 11, 90]
selection_sort(arr)
print("排序结果:", arr)

通过运行以上代码,你可以看到选择排序算法将列表 [64, 34, 25, 12, 22, 11, 90] 按照升序排列后的结果。

选择排序算法不仅简单易懂,而且具有较好的性能。尽管它的时间复杂度为 O(n^2),但在某些情况下,它的性能可能比其他高级排序算法更好。

4 插入排序算法:排序世界的巧妙插珠者

插入排序算法的思想非常巧妙:它将待排序的元素逐个插入到已排序序列的正确位置中。通过不断地比较和交换操作,使得整个序列逐步有序。

以下是Python代码示例,展示了插入排序算法的实现过程:

def insertion_sort(arr):
    n = len(arr)
    
    for i in range(1, n):
        key = arr[i]
        j = i - 1
        while j >= 0 and key < arr[j]:
            # 将大于key的元素后移
            arr[j + 1] = arr[j]
            j -= 1
        
        # 插入key到正确位置
        arr[j + 1] = key

# 测试
arr = [64, 34, 25, 12, 22, 11, 90]
insertion_sort(arr)
print("排序结果:", arr)

通过运行以上代码,你可以看到插入排序算法将列表 [64, 34, 25, 12, 22, 11, 90] 按照升序排列后的结果。

插入排序算法不仅实现简单,而且适用于小型或部分有序的列表。虽然它的平均和最坏情况下的时间复杂度为O(n^2),但在某些情况下,它的性能可能优于其他高级排序算法。

5 快速排序算法:排序世界的分而治之大师

快速排序算法的核心思想是通过选择一个基准元素,将序列分为比基准元素小的一侧和比基准元素大的一侧,然后递归地对两侧的子序列进行排序。

以下是Python代码示例,展示了快速排序算法的实现过程:

def quick_sort(arr, low, high):
    if low < high:
        # 划分序列
        partition_index = partition(arr, low, high)
        
        # 分别对左右子序列进行快速排序
        quick_sort(arr, low, partition_index - 1)
        quick_sort(arr, partition_index + 1, high)
        

def partition(arr, low, high):
    pivot = arr[high]  # 选择最后一个元素作为基准
    i = low - 1  # 指向小于基准的子序列的末尾索引
    
    for j in range(low, high):
        if arr[j] < pivot:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]
    
    arr[i + 1], arr[high] = arr[high], arr[i + 1]
    return i + 1

# 测试
arr = [64, 34, 25, 12, 22, 11, 90]
quick_sort(arr, 0, len(arr) - 1)
print("排序结果:", arr)

通过运行以上代码,你可以看到快速排序算法将列表 [64, 34, 25, 12, 22, 11, 90] 按照升序排列后的结果。

快速排序算法以其高效的平均时间复杂度 O(nlogn) 而被广泛应用。它采用了分治策略,递归地将列表分成更小的子序列,然后通过比较和交换操作将其排序。

6 归并排序算法:排序世界的合而为一大师

归并排序算法的核心思想是将待排序的序列分成两个子序列,不断重复这个过程,直到子序列长度为1。然后,通过合并两个有序的子序列逐步构建有序的结果序列。

以下是Python代码示例,展示了归并排序算法的实现过程:

def merge_sort(arr):
    if len(arr) > 1:
        mid = len(arr) // 2
        left_half = arr[:mid]
        right_half = arr[mid:]
        
        merge_sort(left_half)
        merge_sort(right_half)
        
        merge(arr, left_half, right_half)

def merge(arr, left_half, right_half):
    i = j = k = 0
    
    while i < len(left_half) and j < len(right_half):
        if left_half[i] < right_half[j]:
            arr[k] = left_half[i]
            i += 1
        else:
            arr[k] = right_half[j]
            j += 1
        k += 1
    
    while i < len(left_half):
        arr[k] = left_half[i]
        i += 1
        k += 1
    
    while j < len(right_half):
        arr[k] = right_half[j]
        j += 1
        k += 1

# 测试
arr = [64, 34, 25, 12, 22, 11, 90]
merge_sort(arr)
print("排序结果:", arr)

通过运行以上代码,你可以看到归并排序算法将列表 [64, 34, 25, 12, 22, 11, 90] 按照升序排列后的结果。

归并排序算法以其稳定的时间复杂度 O(nlogn) 和可靠的性能而受到广泛应用。它通过将序列递归地分成两个子序列,然后将这些子序列合并为一个有序的结果序列。

7 堆排序算法:排序世界的二叉堆巨匠

堆排序算法的核心思想是通过构建一个最大堆或最小堆来实现排序。最大堆是一种二叉树结构,每个父节点的值都大于或等于其子节点的值;最小堆则相反,每个父节点的值都小于或等于其子节点的值。通过不断交换根节点和最后一个节点,并对剩余节点进行堆化操作,堆排序算法可以得到一个有序的结果序列。

以下是Python代码示例,展示了堆排序算法的实现过程:

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)

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)

# 测试
arr = [64, 34, 25, 12, 22, 11, 90]
heap_sort(arr)
print("排序结果:", arr)

通过运行以上代码,你可以看到堆排序算法将列表 [64, 34, 25, 12, 22, 11, 90] 按照升序排列后的结果。

堆排序算法以其稳定的平均时间复杂度 O(nlogn) 而被广泛应用。它利用二叉堆的特性,不断交换根节点和最后一个节点,对剩余节点进行堆化操作,从而实现排序。

8 计数排序算法:排序世界的数字统计大师

计数排序算法的核心思想是通过先统计序列中每个元素出现的次数,然后根据这些统计信息将元素按照顺序重新排列。它适用于非负整数的排序,且时间复杂度为O(n+k),其中n是序列的长度,k是序列中出现的最大值。

以下是Python代码示例,展示了计数排序算法的实现过程:

def counting_sort(arr):
    max_value = max(arr)
    count = [0] * (max_value + 1)
    result = [0] * len(arr)
    
    # 统计每个元素出现的次数
    for num in arr:
        count[num] += 1
    
    # 计算每个元素在排序后的序列中的位置
    for i in range(1, max_value + 1):
        count[i] += count[i - 1]
    
    # 构建排序后的序列
    for num in arr:
        result[count[num] - 1] = num
        count[num] -= 1
    
    return result

# 测试
arr = [64, 34, 25, 12, 22, 11, 90]
sorted_arr = counting_sort(arr)
print("排序结果:", sorted_arr)

通过运行以上代码,你可以看到计数排序算法将列表 [64, 34, 25, 12, 22, 11, 90] 按照升序排列后的结果。

计数排序算法以其线性时间复杂度和稳定性而受到广泛应用。它通过统计序列中每个元素的出现次数,并利用这些统计信息构建有序结果序列。

9 基数排序算法:排序世界的位数魔法师

基数排序算法的核心思想是从低位到高位对待排序的元素进行排序。它利用了数字的位数特性,通过多次分配和收集的过程,最终可以得到一个有序的结果。基数排序算法适用于元素为非负整数的排序,且时间复杂度为O(d * (n + k)),其中d是数字的位数,n是序列的长度,k是每个位的取值范围。 以下是Python代码示例,展示了基数排序算法的实现过程:

def counting_sort(arr, exp):
    n = len(arr)
    count = [0] * 10
    result = [0] * n
    
    # 统计每个位上的出现次数
    for i in range(n):
        index = arr[i] // exp
        count[index % 10] += 1
    
    # 计算每个位上元素的位置
    for i in range(1, 10):
        count[i] += count[i - 1]
    
    # 构建排序后的序列
    for i in range(n - 1, -1, -1):
        index = arr[i] // exp
        result[count[index % 10] - 1] = arr[i]
        count[index % 10] -= 1
    
    # 更新原序列
    for i in range(n):
        arr[i] = result[i]

def radix_sort(arr):
    max_value = max(arr)
    exp = 1
    
    # 从低位到高位依次进行排序
    while max_value // exp > 0:
        counting_sort(arr, exp)
        exp *= 10

# 测试
arr = [170, 45, 75, 90, 802, 24, 2, 66]
radix_sort(arr)
print("排序结果:", arr)

通过运行以上代码,你可以看到基数排序算法将列表 [170, 45, 75, 90, 802, 24, 2, 66] 按照升序排列后的结果。

基数排序算法以其高效的时间复杂度和稳定性而受到广泛应用。它利用数字的位数特性,通过多次分配和收集的过程实现排序。

10 深度优先搜索算法:探索图的迷宫穿越之旅

深度优先搜索算法的核心思想是通过递归地探索图的所有可能路径,直到找到目标节点或无法继续前进为止。它通过深入搜索图的每个分支,直到无法再继续为止,然后回溯到上一个节点,继续搜索其他未探索的分支。深度优先搜索常用于解决迷宫问题、图遍历和连通性问题等。

以下是Python代码示例,展示了深度优先搜索算法的实现过程:

def dfs(graph, start, visited):
    # 标记当前节点为已访问
    visited.add(start)
    print(start, end=" ")
    
    # 递归地遍历当前节点的邻接节点
    for neighbor in graph[start]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited)

# 创建图的邻接列表表示
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}
visited = set()

# 从节点'A'开始进行深度优先搜索
dfs(graph, 'A', visited)

通过运行以上代码,你可以看到从节点'A'出发进行深度优先搜索的结果。

深度优先搜索算法以其简单、灵活和可变化的特性而受到广泛应用。它通过递归地探索图的所有可能路径,可以解决许多与图相关的问题。

11 广度优先搜索算法:一步一步扩展探索之旅

广度优先搜索算法的核心思想是利用队列数据结构,逐层扩展搜索目标节点周围的节点。它从起始节点开始,按照距离起始节点的层级顺序逐层探索,并在每一层按照从左到右的顺序对节点进行访问。广度优先搜索常用于解决最短路径问题、连通性问题和寻找图中特定节点等。

以下是Python代码示例,展示了广度优先搜索算法的实现过程:

from collections import deque

def bfs(graph, start):
    visited = set()
    queue = deque([start])
    
    while queue:
        node = queue.popleft()
        if node not in visited:
            print(node, end=" ")
            visited.add(node)
            queue.extend(graph[node])

# 创建图的邻接列表表示
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

# 从节点'A'开始进行广度优先搜索
bfs(graph, 'A')

通过运行以上代码,你可以看到从节点'A'出发进行广度优先搜索的结果。

广度优先搜索算法以其逐层扩展和广泛探索的特性而受到广泛应用。它利用队列数据结构,逐层扩展搜索目标节点周围的节点,可以解决许多与图相关的问题。

12 迪杰斯特拉算法:寻找最短路径的探索之旅

迪杰斯特拉算法(Dijkstra's Algorithm)是一种常用且高效的图算法,用于在带权重的图中寻找从起始节点到目标节点的最短路径。本篇博文将详细介绍迪杰斯特拉算法的原理和实现方法,并提供Python代码,带你一起踏上最短路径的探索之旅。

迪杰斯特拉算法的核心思想是通过启发式的贪心策略,逐步更新起始节点到其他节点的最短距离,并逐步确定最短路径。它维护一个距离表,记录每个节点到起始节点的当前最短距离,并使用优先级队列来选择下一个要扩展的节点。迪杰斯特拉算法常用于路由选择、网络优化和资源分配等问题。

以下是Python代码示例,展示了迪杰斯特拉算法的实现过程:

import heapq

def dijkstra(graph, start):
    distances = {node: float('inf') for node in graph}
    distances[start] = 0
    queue = [(0, start)]
    
    while queue:
        current_distance, current_node = heapq.heappop(queue)
        
        if current_distance > distances[current_node]:
            continue
        
        for neighbor, weight in graph[current_node].items():
            distance = current_distance + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(queue, (distance, neighbor))
    
    return distances

# 创建图的邻接字典表示(使用邻接矩阵也可)
graph = {
    'A': {'B': 5, 'C': 2},
    'B': {'A': 5, 'D': 1, 'E': 6},
    'C': {'A': 2, 'F': 8},
    'D': {'B': 1},
    'E': {'B': 6, 'F': 3},
    'F': {'C': 8, 'E': 3}
}

# 从节点'A'开始使用迪杰斯特拉算法寻找最短路径
start_node = 'A'
shortest_distances = dijkstra(graph, start_node)

# 输出最短路径结果
for node, distance in shortest_distances.items():
    print(f"The shortest distance from {start_node} to {node} is {distance}")

通过运行以上代码,你可以得到从起始节点'A'到其他节点的最短距离结果。

迪杰斯特拉算法以其高效且准确的特性而受到广泛应用。它利用启发式的贪心策略逐步更新最短距离,并逐步确定最短路径。

13 动态规划算法:优化子问题,实现最优解之旅

动态规划(Dynamic Programming)算法是一种常用且强大的算法技术,用于解决具有重叠子问题性质的优化问题。动态规划的关键思想是将一个大问题分解为多个重叠子问题,并保存子问题的解,以避免重复计算。通过自底向上或自顶向下的方式,动态规划算法逐步求解子问题,最终得到问题的最优解。动态规划广泛应用于求解背包问题、路径计数问题、最长公共子序列问题以及其他许多复杂的优化问题。

以下是Python代码示例,展示了动态规划算法的实现过程:

def fibonacci(n):
    fib = [0, 1]
    
    for i in range(2, n+1):
        fib.append(fib[i-1] + fib[i-2])
    
    return fib[n]

# 计算斐波那契数列的第10个数
n = 10
result = fibonacci(n)

print(f"The Fibonacci number at index {n} is {result}")

通过运行以上代码,你可以得到斐波那契数列中第10个数的结果。

动态规划算法通过优化子问题的求解,实现了高效的最优解求解过程。它将一个大问题分解为多个重叠子问题,并使用存储技术避免重复计算,从而提高算法的效率。

标签:arr,20,image,编程,程序员,算法,排序,节点,def
From: https://blog.51cto.com/u_15229916/7159266

相关文章

  • 8.20题解
    T1sun暴力枚举即可时间复杂度分析:\((lnx)'=\frac{1}{x}\)根据牛顿-莱布尼茨公式可得:\(\sum_{x=1}^{n}{\frac{1}{x}}=\int_{1}^{n}{\frac{1}{x}}=ln(n)-ln{1}=ln(n)\)令\(ln(n)=k\)可得:\(n=e^{k}<=e^{15}\approx3269017\)T2order首先需要理解题意......
  • 2023.33 AI框架
    人工智能(AI)框架是指用于构建和部署AI模型的软件工具集合,它们提供了各种算法、模型和工具,简化了AI开发过程。AI框架的发展历史:早期AI框架:在AI的早期阶段,一些基础的编程语言和库被用于实现简单的机器学习算法,如MATLAB、R和Python的NumPy库。这些工具提供了基本的数据处理和数学运算......
  • PhotoShop 2023下载-功能强大的图片编辑软件 系列软件
    AdobePhotoshop,简称“PS”,是一个由Adobe公司开发和发行的图像处理软件。它可以编辑和合成多个图层中的位图,支持图层遮罩、图像合成。除了位图之外,它还具有编辑或渲染文本、矢量图形、3D图形和视频,并且PS还支持外部插件来拓展其功能。其中,PhotoshopCC2019于2018年10月15日发布。......
  • Adobe Photoshop官方软件Photoshop 2022正式版下载 系列软件
    Photoshop2022v23.0.2.101是由Adobe公司最新推出的高效、专业、实用的图像处理软件,同时该软件主要是以其强悍的编辑和调整、绘图等功能得到广泛的应用,其中还有各种图片的调整和图画绘制以及图像的修复、调色等一系列的工具都是数不胜数,使用范围也是非常的广,我们从照片修饰到海报......
  • 「PR安装教程」2023最新版!PR下载安装免费教程 系列软件
    AdobePremiereProCC中文精简版是一款适用于专业视频制作与编辑的工具软件,AdobePremiereProCC强大、可自定义、非线性的编辑器,可让您随心所欲地精准编辑视频。PremiereCC提供了几种新功能和增强功能,可充实您的数字视频剪辑体验。软件地址:看置顶贴pr2021新功能1、ARRIProRe......
  • Pr-官版下载-Premiere-2023正版-永久使用 系列软件
    软件特色1、导入任何文件格式的镜头。轻松拖放视频文件至您的项目。无论您是用DSLR、GoPro还是iPhone—或其它智能手机—进行摄像,都可以使用PremierePro视频编辑软件制作。2、精确修剪镜头。使用修剪工具在时间线上进行直观编辑,延长或缩短电影剪辑。凭借PremierePro的直观编辑流......
  • 2023.8.20学长分享
    Exeabow_sky点分治树上路径统计或最优化。(无根树)找重心,分别考虑子树,标vis。复杂度O(nlogn)路径合并信息。对于较多次的查询可以用点分树;或离线,一次点分治处理完。[CSP-S2022T4]也可点分治。对于k=2,对链在点分治中维护信息,离线;对分治中心h,对两子树中点a,b,做like-DP,......
  • Linux网络编程(epoll的ET模式和LT模式)
    (文章目录)前言本篇文章主要来讲解epoll的ET模式和LT模式,epoll中有两种模式可以选择一种是ET模式(边缘触发模式),另一种是LT模式(水平触发模式)一、ET模式和LT模式概念讲解1.水平触发模式(LT,Level-Triggered)在水平触发模式下,当一个文件描述符上的I/O事件就绪时,epoll会立即通知......
  • 异步编程:promise and future
    本文介绍C++中异步编程相关的基础操作类,以及借鉴promiseandfuture思想解决回调地狱介绍。std::threadandstd::jthreadstd::thread为C++11引入,一个简单的例子如下:classWorkerfinal{public:voidExecute(){std::cout<<__FUNCTION__<<std::endl;}......
  • P1 P2508 [HAOI2008]圆上的整点
    [HAOI2008]圆上的整点23.3.22WE.真是一道神题,特别是对于刚得了甲流滚回家摆烂从而有时间乱看而恰巧这几天上课刚学复数的我。一直很好奇复数到底是什么,昨天晚上刷B站学习偶然看到了一个解释虚数的视频,结果也没看懂,只听说乘上一个\(i\)相当于旋转\(90^{\circ}\),一想还真是!......