菜单

算法

相关源文件

本页面概述了 Hello Algo 存储库中涵盖的基础算法。它解释了不同的算法范式、它们的实现和分析方法。有关这些算法的计算复杂性分析,请参阅 计算复杂性

算法概述

算法是解决特定问题的分步过程。在 Hello Algo 存储库中,算法根据它们解决问题的方法和技术分为几个主要类别。这些算法构成了计算机科学的核心,对于高效的数据处理和问题解决至关重要。

来源: docs/chapter_computational_complexity/time_complexity.md1049-1071 docs/chapter_searching/binary_search.md1-21 docs/chapter_sorting/bubble_sort.md1-5 docs/chapter_sorting/quick_sort.md1-9

搜索算法

查找算法旨在在数据结构中查找特定元素。该存储库涵盖了两种主要的查找算法类型:

线性搜索是一种简单的搜索算法,它按顺序检查每个元素,直到找到目标或到达数据结构的末尾。它适用于已排序和未排序的数组,时间复杂度为 O(n)。

二分搜索是一种在已排序数组中查找元素的有效算法。它采用分治方法,通过重复地将搜索间隔分成两半。

该算法的工作原理如下:

  1. 初始化指向数组开头和结尾的指针
  2. 查找中间元素并与目标进行比较
  3. 如果目标与中间元素匹配,则返回索引
  4. 如果目标小于中间元素,则搜索左半部分
  5. 如果目标大于中间元素,则搜索右半部分
  6. 重复此过程,直到找到目标或搜索间隔为空

二分搜索的时间复杂度为 O(log n),对于大型数组来说,它比线性搜索效率高得多。

来源: docs/chapter_searching/binary_search.md1-21 docs/chapter_computational_complexity/time_complexity.md1139-1155

排序算法

排序算法将元素按特定顺序(通常是升序或降序)排列。该存储库涵盖了多种具有不同时间复杂度的排序算法:

冒泡排序

冒泡排序是一种简单的基于比较的算法,它会重复遍历列表,比较相邻的元素,如果它们的顺序错误就交换它们。重复遍历列表,直到列表排序完成。

时间复杂度:O(n²)

来源: docs/chapter_sorting/bubble_sort.md1-5 docs/chapter_computational_complexity/time_complexity.md1102-1118

快速排序

快速排序是一种高效的分治排序算法,它通过选择一个“枢轴”元素并围绕枢轴对数组进行分区来实现。然后,该算法递归地对子数组进行排序。

关键步骤

  1. 选择一个枢轴元素(通常是第一个或最后一个元素)
  2. 分区数组,使小于枢轴的元素位于左侧,大于枢轴的元素位于右侧
  3. 递归地将相同的过程应用于子数组

时间复杂度:平均情况 O(n log n),最坏情况 O(n²)

来源: docs/chapter_sorting/quick_sort.md1-9 docs/chapter_computational_complexity/time_complexity.md1174-1182

高级算法范式

除了基本的搜索和排序之外,该存储库还涵盖了多种高级算法范式:

分治法

分治是一种将问题分解为更小的、相似的子问题,独立地解决它们,然后合并结果来解决原始问题的范式。

例如,二分搜索、归并排序和快速排序。

时间复杂度:基于此方法实现的排序算法通常为 O(n log n)。

来源: docs/chapter_computational_complexity/time_complexity.md1139-1155 docs/chapter_computational_complexity/time_complexity.md1174-1182

动态规划

动态规划通过将复杂问题分解为更简单的子问题,并存储子问题的结果以避免重复计算来解决问题。

主要特性

  • 重叠子问题:子问题的解可以被多次复用
  • 最优子结构:问题的最优解包含子问题的最优解

常见的应用包括背包问题、硬币找零问题和编辑距离。

来源: docs/chapter_computational_complexity/time_complexity.md1049-1071

回溯

回溯法是一种算法技术,它通过增量方式构建解决方案,并在确定解决方案无效时放弃该解决方案(“回溯”)。

应用包括解决 N 皇后问题、排列和子集和问题。

时间复杂度:由于搜索的穷举性质,通常为指数级 O(2ⁿ) 或阶乘级 O(n!)。

来源: docs/chapter_computational_complexity/time_complexity.md1119-1138 docs/chapter_computational_complexity/time_complexity.md1183-1201

贪心算法

贪心算法在每一步做出局部最优选择,以期找到全局最优解。它们通常用于优化问题,但不一定能保证最优解。

来源: docs/chapter_computational_complexity/time_complexity.md1049-1071

算法分析

时间复杂度

时间复杂度描述了算法的运行时间如何随着输入大小的增加而增长。该存储库使用大 O 符号来表示时间复杂度。

常见时间复杂度类别(从快到慢)

  • O(1):常数时间
  • O(log n):对数时间
  • O(n):线性时间
  • O(n log n):对数线性时间
  • O(n²):平方时间
  • O(2ⁿ):指数时间
  • O(n!):阶乘时间

来源: docs/chapter_computational_complexity/time_complexity.md1049-1071 docs/chapter_computational_complexity/time_complexity.md1072-1112

空间复杂度

空间复杂度分析了算法相对于输入大小所使用的内存量。在分析空间复杂度时,我们侧重于:

  • 临时存储空间
  • 堆栈帧空间(用于递归调用)
  • 输出空间

高效的算法可以最小化时间和空间复杂度,尽管两者之间常常存在权衡。

来源: docs/chapter_computational_complexity/space_complexity.md1-25

算法数据结构

不同的算法使用不同的数据结构来实现最佳性能。

来源: docs/chapter_array_and_linkedlist/array.md1-16 docs/chapter_array_and_linkedlist/linked_list.md1-15 docs/chapter_stack_and_queue/stack.md1-23 docs/chapter_stack_and_queue/queue.md1-21 docs/chapter_tree/binary_tree.md1-16 docs/chapter_tree/binary_search_tree.md1-16 docs/chapter_tree/avl_tree.md1-16 docs/chapter_heap/heap.md1-23 docs/chapter_hashing/hash_map.md1-24

算法性能对比

下表比较了仓库中实现的各种算法的时间复杂度

算法类别算法最佳情况平均情况最坏情况空间复杂度
搜索线性搜索O(1)O(n)O(n)O(1)
二分搜索O(1)O(log n)O(log n)O(1)
排序冒泡排序O(n)O(n²)O(n²)O(1)
快速排序O(n log n)O(n log n)O(n²)O(log n)
数据结构操作哈希表查找O(1)O(1)O(n)O(n)
二叉搜索树操作O(log n)O(log n)O(n)O(n)
堆操作O(1)O(log n)O(log n)O(n)

来源: docs/chapter_computational_complexity/time_complexity.md1049-1201 docs/chapter_computational_complexity/space_complexity.md1-25

实现与使用

Hello Algo 提供多种编程语言的算法实现,使开发者能够根据自己偏好的语言来理解和使用这些算法。

在实现或使用这些算法时,请考虑:

  1. 输入约束:确保您的输入满足算法的要求(例如,二分查找要求输入数组已排序)
  2. 边界情况:处理诸如空输入或边界条件等边界情况
  3. 时间和空间复杂度权衡:根据您的具体约束选择合适的算法
  4. 算法变种:某些算法有针对特定场景优化的变种

有关具体的实现和详细的解释,请参阅仓库中的相关章节。

来源: docs/chapter_searching/binary_search.md1-21 docs/chapter_sorting/bubble_sort.md1-5 docs/chapter_sorting/quick_sort.md1-9