算法学习笔记(Hello算法)—— 初识算法

1、相关链接

Hello算法:Hello 算法 (hello-algo.com)

2、算法是什么

2.1 算法定义

算法是一系列明确、有限且有效的步骤或指令的集合,用于解决特定问题或执行特定任务。

算法具有以下基本特征:

  • 输入:算法至少有一个输入(某些算法可能有多个输入),或者可以没有输入。
  • 输出:算法必须至少产生一个输出,这个输出是解决问题的结果。
  • 明确性:算法中的每一步都必须清晰无误,不能有歧义。
  • 有限性:算法必须在有限的时间内完成,不能无限循环下去。
  • 可行性:算法的每一步都应该是基本操作,可以被实际执行。
2.2 数据结构定义

数据结构(Data Structure)是计算机存储、组织数据的方式。它是计算机科学中的一个重要概念,主要目的是使数据的存储和访问更加高效、方便。数据结构根据其性质和用途,可以分为多种不同的类型。

不同数据元素之间不是独立的,而是存在特定的关系,我们将这些关系称为结构。

以下是数据结构的基本定义:

  1. 数据对象的集合:数据结构是数据对象(或称为元素、值)的集合,这些对象可以是数字、字符、记录等。

  2. 数据对象之间的关系:数据结构不仅包含数据对象,还包含数据对象之间的关系。这些关系定义了数据对象是如何组织和联系的。

  3. 操作的集合:数据结构通常伴随着一系列预定义的操作,这些操作可以创建、修改、访问和删除数据结构中的数据。

数据结构的主要类型包括:

  • 逻辑结构:这是从逻辑关系角度描述数据结构的,不考虑数据在计算机中的实际存储方式。常见的逻辑结构有:

    • 集合
    • 线性结构(如数组、链表、栈、队列)
    • 树形结构(如二叉树、多叉树、堆)
    • 图形结构(如无向图、有向图)
  • 物理结构:这是数据结构在计算机中的实际存储方式,描述了数据的物理位置关系。常见的物理结构有:

    • 顺序存储结构:数据元素在内存中连续存放。
    • 链式存储结构:数据元素可以分散存储,通过指针连接。

数据结构的选择对算法的设计和程序的效率有着重要的影响。不同的数据结构适合解决不同类型的问题,例如:

  • 数组适合随机访问,但不适合频繁的插入和删除操作。
  • 链表适合频繁的插入和删除操作,但随机访问效率较低。
  • 结构适合表示具有层次或网状关系的数据。
2.3 数据结构和算法的关系

数据结构与算法之间有着紧密的关系,它们相辅相成,共同构成了计算机科学的核心内容。以下是数据结构与算法关系的几个方面:

算法依赖于数据结构

  • 算法的设计往往需要根据待处理数据的特性来选择合适的数据结构。例如,排序算法通常需要数组这种可以随机访问的数据结构,而图算法则需要用到图这种可以表示复杂关系的结构。
  • 不同的数据结构可以影响算法的效率。例如,在链表和数组上实现排序算法,其时间和空间复杂度可能会有显著差异。

数据结构为算法提供服务

  • 数据结构提供了存储和管理数据的手段,使得算法能够高效地读取和修改数据。
  • 数据结构封装了一些基本操作,如插入、删除、查找等,这些操作是算法实现的基础。

算法实现数据结构的操作

  • 数据结构定义了一组操作,而算法则是这些操作的实现。例如,链表数据结构定义了插入和删除操作,具体的插入和删除算法则决定了这些操作如何执行。

算法效率受数据结构影响

  • 数据结构的选择直接影响算法的性能。例如,哈希表提供了平均情况下常数时间的查找效率,而二叉搜索树则提供了对数时间的查找效率。
  • 合适的数据结构可以降低算法的时间复杂度和空间复杂度。

2.4 其他定义

数据:是描述害观事物的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。数据不仅仅包括整型、实型等数值类型’还包括字符及声音、图像、视频等非数值类型。·

数据元素:是组成数据的、有一定意义的墓本单位,在计算机中通常作为整体处理,也被称为记录。

数据顶:—个数据元素可以由若干个数据顶组成。

比如人这样的数据元素,可以有眼睛、耳朵、鼻子、嘴巴、手、脚这些数据项,也可以有姓名、年龄、性别、家庭地址、联系电话、邮政编码等数据项,具体有哪些数据项,要由你做的系统来决定。

数据项是数据不可分割的最小单位。

数据对象:呈性质相同的数据元素的集合,是数据的子集。

2.算法复杂度分析

在算法设计中,我们先后追求以下两个层面的目标。

  • 找到问题解法:算法需要在规定的输入范围内可靠地求得问题的正确解。
  • 寻求最优解法:同一个问题可能存在多种解法,我们希望找到尽可能高效的算法。

算法效率已成为衡量算法优劣的主要评价指标,它包括以下两个维度。

  • 时间效率:算法运行速度的快慢。 ‧
  • 空间效率:算法占用内存空间的大小。

效率评估方法主要分为两种:实际测试、理论估算。

实际测试的优点和缺点

优点:

  • 实际反映:实际测试可以在真实的硬件和软件环境下运行算法,能够反映出算法在实际使用中的性能,包括执行时间和内存消耗。
  • 易于理解:测试结果通常以直观的数字形式呈现,易于非专业人士理解。
  • 发现隐藏问题:在测试过程中可能会发现算法在实际应用中才会出现的隐藏问题,如并发执行时的竞态条件、内存泄漏等。
  • 比较不同系统:通过在不同系统上进行测试,可以比较算法在不同环境下的表现。

缺点:

  • 时间消耗:进行实际测试需要花费大量时间,特别是对于复杂算法和大数据集。
  • 可能不全面:测试可能只覆盖了算法的部分功能或特定数据集,无法全面评估算法的性能。
  • 环境依赖:测试结果受测试环境(如CPU、内存、操作系统等)的影响,可能不具有普遍性。
  • 结果解释困难:有时候测试结果可能会因为外部因素(如系统负载)而出现波动,解释这些波动可能比较困难。

理论估算的优点和缺点

优点:

  • 普适性:理论估算通常基于数学模型,可以在不考虑具体硬件和软件环境的情况下评估算法的性能。
  • 预测性:理论分析可以帮助预测算法在不同规模数据上的表现,特别是在大数据集上。
  • 成本低:与实际测试相比,理论估算通常不需要实际的硬件资源,成本较低。
  • 指导意义:理论分析可以为算法改进提供方向,帮助开发者理解算法的局限性。

缺点:

  • 抽象性:理论估算往往较为抽象,可能难以被非专业人士理解。
  • 忽略实际因素:理论模型可能无法完全反映现实世界中的所有因素,如磁盘I/O、网络延迟等。
  • 可能不准确:理论估算基于假设,如果这些假设与实际情况不符,估算结果可能不准确。
  • 复杂度高:对于复杂算法,进行理论分析可能需要高级数学知识和复杂的推导过程。

总的来说,实际测试和理论估算是互补的。在实际应用中,通常会结合这两种方法来全面评估算法的效率。理论估算可以提供一个初步的指导,而实际测试则可以验证理论分析的结果,并发现实际应用中可能遇到的问题。

2.2 迭代与递归

两种基本的程序控制结构:迭代、递归。

2.2.1 迭代

迭代(Iteration)是一种在计算过程中重复执行一系列操作的方法或概念。在编程和算法设计中,迭代通常指的是通过循环结构来重复执行一段代码,直到满足某个终止条件。

  • for循环:当知道迭代的次数时使用。

  • while循环:当迭代的次数未知,但知道何时停止时使用。

  • do-while循环(某些语言中):至少执行一次循环体,然后根据条件决定是否继续迭代。

  • 嵌套循环:在一个循环结构内嵌套另一个循环结构

public class Fibonacci {public static void main(String[] args) {int n = 10; // 例如,计算斐波那契数列的第10个数int result = fibonacciIterative(n);System.out.println("斐波那契数列的第" + n + "个数是: " + result);}// 迭代方法计算斐波那契数列public static int fibonacciIterative(int n) {if (n <= 1) {return n;}int fib = 1;int prevFib = 1;for (int i = 2; i < n; i++) {int temp = fib;fib += prevFib;prevFib = temp;}return fib;}
}
2.2.2 递归

递归(Recursion)是一种编程和算法设计中的技术,它涉及函数或方法调用自身以解决一个更小或更简单的问题。递归通常用于解决那些可以分解为相似子问题的问题。

递归的基本要素:

  • 基线条件(Base Case):这是递归终止的条件。基线条件是递归算法必须达到的一个简单情况,它可以直接解决而无需进一步递归。(终止条件:用于决定什么时候由“递”转“归”。)

  • 递归步骤(Recursive Step):这是算法中递归调用的部分,它将问题分解为更小的子问题。(返回结果:对应“归”,将当前递归层级的结果返回至上一层。)

  • 递归调用(Recursive Call):这是函数或方法调用自身的操作,通常输入更小或更简化的参数。

以下是一个使用递归在Java中计算阶乘的案例。阶乘是一个经典的递归问题,其中n!(n的阶乘)定义为n * (n-1) * (n-2) * ... * 1,并且0!被定义为1

public class Factorial {// 递归方法计算阶乘public static int factorial(int n) {// 基线条件:如果n为0,返回1if (n == 0) {return 1;}// 递归步骤:n! = n * (n-1)!return n * factorial(n - 1);}public static void main(String[] args) {int number = 5; // 示例:计算5的阶乘int result = factorial(number);System.out.println(number + "! = " + result);}
}

迭代与递归可以得到相同的结果,但它们代表了两种完全不同的思考和解决问题的范式。

  • 迭代:“自下而上”地解决问题。从最基础的步骤开始,然后不断重复或累加这些步骤,直到任务完成。
  • 递归:“自上而下”地解决问题。将原问题分解为更小的子问题,这些子问题和原问题具有相同的形式。
  • 迭代:在循环中模拟求和过程,从 1 遍历到 𝑛 ,每轮执行求和操作,即可求得 𝑓(𝑛) 。
  • 递归:将问题分解为子问题 𝑓(𝑛) = 𝑛+𝑓(𝑛−1) ,不断(递归地)分解下去,直至基本情况 𝑓(1) = 1 时终止。

不同点:

  • 定义方式

    • 递归:函数自身调用自身。
    • 迭代:通过循环结构重复执行一系列操作。
  • 内存使用

    • 递归:通常使用更多的内存,因为每次函数调用都需要在调用栈上保存信息。
    • 迭代:通常使用更少的内存,因为它不需要额外的栈空间。
  • 性能

    • 递归:在某些情况下可能比迭代慢,因为它涉及更多的函数调用开销。
    • 迭代:通常在运行时更高效,因为它减少了函数调用的开销。
  • 代码简洁性

    • 递归:可以使代码更简洁,更易于理解,尤其是对于某些自然递归的问题,如树遍历、分治算法等。
    • 迭代:可能需要更多的代码来处理循环和状态变量,有时这会使代码更难理解。
  • 可读性和维护性

    • 递归:对于某些问题,递归解决方案更符合人的直观思维。
    • 迭代:有时迭代代码更直观,尤其是在简单的循环结构中。
  • 深度限制

    • 递归:可能会遇到调用栈深度限制,导致栈溢出错误。
    • 迭代:不会遇到栈深度限制问题。
  • 控制流程

    • 递归:控制流程的转移是通过函数调用和返回来实现的。
    • 迭代:控制流程的转移是通过循环条件来控制的。
2.2.3 尾递归

尾递归是一种特殊的递归形式,它在函数的末尾直接返回递归调用的结果,而不进行其他操作。尾递归与普通递归的不同之处在于,尾递归的递归调用是函数执行的最后一个动作。这意味着在递归调用之后,不需要执行任何额外的计算。

求和操作是在“递”的过程中执行的,“归”的过程只需层层返回。

特点:

  • 递归调用是最后一条执行语句:在尾递归中,递归调用是函数体中执行的最后一个操作,没有后续的操作需要执行。

  • 无额外状态:尾递归函数不需要在每次递归调用时保存额外的状态信息,因为递归调用后没有其他操作需要这些信息。

  • 优化可能性:某些编译器或解释器可以优化尾递归,将其转换为迭代,从而避免增加调用栈的深度,减少内存使用。

优点:

  • 节省内存:因为编译器可以优化尾递归,所以它不会像普通递归那样消耗调用栈空间,从而可以处理更大的输入而不会导致栈溢出。

  • 性能:尾递归通常比普通递归更高效,因为它可以避免额外的函数调用开销。

缺点:

  • 编写限制:并不是所有递归算法都可以轻易地转换为尾递归形式。

  • 编译器支持:尾递归优化不是所有编译器或解释器都支持的,如果编译器不支持尾递归优化,那么尾递归和普通递归在性能和内存使用上没有区别。

2.2.4 递归树
public class Fibonacci {public static void main(String[] args) {int n = 10; // 例如,计算斐波那契数列的第10个数int result = fibonacciRecursive(n);System.out.println("斐波那契数列的第" + n + "个数是: " + result);}// 递归方法计算斐波那契数列public static int fibonacciRecursive(int n) {if (n <= 1) {return n;}return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);}
}

观察以上代码,我们在函数内递归调用了两个函数,这意味着从一个调用产生了两个调用分支。如图所示,这样不断递归调用下去,最终将产生一棵层数为 𝑛 的递归树(recursion tree)。

2.2.5 两者对比

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/48150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaScript 算法】图的遍历:理解图的结构

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、深度优先搜索&#xff08;DFS&#xff09;深度优先搜索的步骤深度优先搜索的JavaScript实现 二、广度优先搜索&#xff08;BFS&#xff09;广度优先搜索的步骤 三、应用场景四、总结 图的遍历是图论中的基本操作之一&am…

院内影像一体化平台PACS源码,C#语言的PACS/RIS系统,二级医院应用案例

全院级PACS系统源码&#xff0c;一体化应用系统整合&#xff0c;满足放射、超声、内窥镜中心、病理、检验等多个科室的工作流程和需求&#xff0c;为不同科室提供专业的解决方案&#xff0c;实现了全院乃至区域内信息互联互通、数据统一存储与管理等功能&#xff0c;做到以病人…

浪漫情怀:红酒中的诗意与情感

在生活的点滴细节中&#xff0c;总有些元素能触动我们内心较柔软的地方&#xff0c;唤起那份深深的浪漫情怀。而红酒&#xff0c;便是这其中的一种神奇媒介。它以其不同的色泽、香气和口感&#xff0c;让人沉醉其中&#xff0c;感受那份诗意与情感的交织。今天&#xff0c;就让…

C语言 | Leetcode C语言题解之第237题删除链表中的节点

题目&#xff1a; 题解&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/void deleteNode(struct ListNode* node) {struct ListNode * p node->next;int temp;temp node->val;node->val…

常见排序算法总结

文章目录 比较排序冒泡排序选择排序插入排序归并排序快速排序堆排序希尔排序 非比较排序&#xff08;桶排序&#xff09;计数排序基数排序 比较排序 冒泡排序 嵌套循环&#xff0c;每次内层循环执行时&#xff0c;数组的每两个元素交换&#xff0c;将一个最大/小的数排到数组…

AIGC代码学习记录

本文主要记录不同的SD模型代码中实现的一些细节&#xff0c;如text2img,img2img,inpaint等等 1. 文生图 第一步&#xff1a;生成随机的latent feature (n,4,64,64)&#xff1b;n为生成的图片个数&#xff1b; 第二步&#xff1a;对于prompt用clip生成特征&#xff0c;正向提示…

PDF-Extract-Kit (PDF内容抽取开源项目)

Github 地址&#xff1a;https://github.com/opendatalab/PDF-Extract-Kit 整体介绍 PDF文档中包含大量知识信息&#xff0c;例如文本、表格、图像、公式等。此外&#xff0c;PDF的文档布局也相当复杂&#xff0c;页眉、页脚、表格标题、图片标题等等&#xff0c;提取高质量的…

python调用chrome浏览器自动化如何选择元素

功能描述&#xff1a;在对话框输入文字&#xff0c;并发送。 注意&#xff1a; # 定位到多行文本输入框并输入内容。在selenium 4版本中&#xff0c;元素定位需要填写父元素和子元素名。 textarea driver.find_element(By.CSS_SELECTOR,textarea.el-textarea__inner) from …

2024.04最新 鹦鹉优化算法 (PO) 开源MATLAB代码

!!!只需要代码的直接跳转到最后一节&#xff0c;有开源代码 1.算法简介2.灵感来源与核心思想2.1 灵感来源2.2 核心思想 3.主要步骤3.1 种群初始化3.2 觅食行为3.3 停留行为3.4 交流行为3.5 对陌生人的恐惧行为 4.伪代码与核心代码4.1流程图与伪代码流程图伪代码 4.2 核心代码(P…

nodejs下载+react安装

一、nodejs安装 1、nodejs下载 具体安装可参考连接&#xff1a;2023最新版Node.js下载安装及环境配置教程&#xff08;非常详细&#xff09;从零基础入门到精通&#xff0c;看完这一篇就够了_nodejs安装及环境配置-CSDN博客 下载地址&#xff1a;Node.js — 下载 Node.js 测…

ubuntu 更新源

前言 实现一键替换在线源 一键更新源 ubuntu 全球镜像站以下支持现有ubuntu 20&#xff0c;22&#xff0c;24 echo "Delete the default source" rm -rf /etc/apt/sources.listecho "Build a new source" cat <<EOF>>/etc/apt/sources.li…

微信小程序 button样式设置为图片的方法

微信小程序 button样式设置为图片的方法 background-image background-size与background-repeat与border:none;是button必须的 <view style" position: relative;"><button class"customer-service-btn" style"background-image: url(./st…

MVC架构在Web开发中的实现

MVC架构在Web开发中的实现 1、MVC架构概述2、MVC架构的实现 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Web开发领域&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;架构模式是一种广泛使用的软件设计模式&#xff0c…

【学习笔记】虚幻SkeletalMesh学习(一)基础介绍

文章目录 零、前言一、资源介绍1.1 骨架资源1.2 骨架网格体资源 二、UE4中的定义2.1 骨骼数据2.2 模型网格数据 三、渲染3.1 RenderData的初始化3.2 渲染对象的创建3.3 渲染对象的更新3.3.1 游戏线程的更新&#xff08;*FSkeletalMeshObjectGPUSkin::Update*&#xff09;3.3.2 …

Android11 framework 禁止三方应用开机自启动

Android11应用自启动限制 大纲 Android11应用自启动限制分析验证猜想&#xff1a;Android11 AOSP是否自带禁止三方应用监听BOOT_COMPLETED​方案禁止执行非系统应用监听到BOOT_COMPLETED​后的代码逻辑在执行启动时判断其启动的广播接收器一棍子打死方案&#xff08;慎用&#…

矩阵形式的bezier曲线

本文分享一段矩阵形式的bezier代码&#xff1a; clc clear% 控制点 P [25;10;5;13]; %% 获得M矩阵 n length(P) - 1; M zeros(n1,n1); for i 1:n1for j 1:n1if(ij<n3)M(i,j) (-1)^(n -i-j2)*nchoosek(n,n-i1)*nchoosek(n-i1,j-1);elseM(i,j) 0;endend end t_temp l…

buu做题(5)

目录 [GXYCTF2019]禁止套娃 方法一: 方法二: [NCTF2019]Fake XML cookbook [GXYCTF2019]禁止套娃 页面里啥也没有 使用dirsearch 扫一下目录 发现有 git 使用工具githack拉取源码 <?php include "flag.php"; echo "flag在哪里呢&#xff1f;<br&g…

PostgreSQL使用(三)

说明&#xff1a;本文介绍PostgreSQL的数据类型和运算符&#xff1b; 数据类型 常用的数据类型如下&#xff1a; 运算符 如下&#xff1a; 运算符的优先级如下&#xff1a; 不需要强记硬背&#xff0c;只需要记住括号可以提高运算符的优先级即可&#xff1b; 总结 本文介绍…

【JavaEE进阶】——Spring AOP

目录 &#x1f6a9;Spring AOP概述 &#x1f6a9;Spring AOP快速⼊⻔ &#x1f393;引入AOP依赖 &#x1f393;编写AOP程序 &#x1f6a9;Spring AOP 详解 &#x1f393;Spring AOP核⼼概念 &#x1f393;通知类型 &#x1f393;PointCut &#x1f393;切⾯优先级 Ord…

【JavaScript 算法】拓扑排序:有向无环图的应用

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、算法原理二、算法实现方法一&#xff1a;Kahn算法方法二&#xff1a;深度优先搜索&#xff08;DFS&#xff09;注释说明&#xff1a; 三、应用场景四、总结 拓扑排序&#xff08;Topological Sorting&#xff09;是一种…