算法入门学习

article/2025/9/15 22:22:33

算法

  • 1. 算法
    • 1.1 什么是算法?
    • 1.2 算法的质量评价指标
      • 1.2.1 时间复杂度
        • 1.2.1.1 常见的时间复杂度量级(效率从高到低)
          • 1.2.1.1.1 常数阶O(1)
          • 1.2.1.1.2 对数阶O(log n)
          • 1.2.1.1.3 线性阶O(n)
          • 1.2.1.1.4 线性对数阶O(n * log n)
          • 1.2.1.1.5 平方阶O(n^2)
          • 1.2.1.1.6 立方阶O(n^3)
          • 1.2.1.1.7 K次方阶O(n^k)
          • 1.2.1.1.8 指数阶O(2^n)
      • 1.2.2 空间复杂度
        • 1.2.2.1 常见的空间复杂度
          • 1.2.2.1.1 O(1)
          • 1.2.2.1.2 O(n)
          • 1.2.2.1.3 O(n^2)
      • 1.3 常用排序算法
        • 1.3.1 冒泡排序
        • 1.3.2 选择排序
        • 1.3.3 归并排序
          • 1.3.3.1 合并排序
          • 1.3.3.2 递归拆分数组
          • 1.3.3.3 递归合并排序---归并排序

1. 算法

1.1 什么是算法?

算法指用系统的方法描述解决问题的策略机制。通俗点讲就是求解问题的方法的方法。

1.2 算法的质量评价指标

1.2.1 时间复杂度

时间复杂度是指问题求解方法的时间效率,由于机器性能等外部环境差异可能会导致同一代码在不同机器上运行的时间不同,所以,严格意义上讲,衡量算法的时间是十分困难的。但是,即使存在这样的外部环境差异,算法的执行时间还是与语句的执行次数成正比的。因此,我们在一定程度上可以通过计算语句的执行次数来推断算法的执行时间。

语句的执行次数被称为时间频度(语句频度),记为T(n)。其中T表示的是最多次数(Times),n表示的是求解问题的规模。所以T(n)表示当问题规模为n时的最多执行次数。

T必须是规模n的最多执行次数才行,这样T(n)才是一个函数,而不是一种相关性。因为如果T不是最多执行次数,那我们还得考虑规模n之下的T到底是什么情况,那么T就可能存在许多值。所以只有当T为最大值时,无论n为多少,T都是一个唯一确定的值,这也就构成了函数关系。

/*案例分析---百元买百鸡公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱。
*///---A方法---
for(int a=1;a<=100;a++){for(int b=1;b<=100;b++){for(int c=1;c<=100;c++){if(a*5+b*3+c/3==100 && a+b+c==100 && c%3==0){System.out.println("公鸡:"+a+"只, 母鸡"+b+", 小鸡"+c);}}}
}
/* A方法时间频度计算:第一层for循环:执行100次第二层for循环:执行100^2次第三层for循环:执行100^3次
*///---B方法---
for(int a=1;a<=100;a++){for(int b=1;b<=100;b++){c=100-a-b;if(a*5+b*3+c/3==100 && c%3==0){System.out.println("公鸡:"+a+"只, 母鸡"+b+", 小鸡"+c);}}
}
/*B方法时间频度计算:第一层for循环:执行100次第二层for循环:执行100^2次
*/

通过上面这个案例,A、B算法孰优孰劣一览无余,但时间频度不等于时间复杂度。时间复杂度可以看作是时间频度的极限。比如上例,当n趋向于无穷的时候,A、B的时间频度又如何表示呢?我们用O(n)表示时间复杂度,当n趋向于无穷时,T(n)=O(n),所以
A的时间复杂度O(n)=n^3
B的时间复杂度O(n)=n^2

1.2.1.1 常见的时间复杂度量级(效率从高到低)

1.2.1.1.1 常数阶O(1)
int i=1;
i++;
...
1.2.1.1.2 对数阶O(log n)
for(int i=1;i<n;i*=2){
}
1.2.1.1.3 线性阶O(n)
for(int i=1;i<n;i++){
}
1.2.1.1.4 线性对数阶O(n * log n)
for(int i=1;i<n;i++){for(int j=1;j<n;j*=2){}
}
1.2.1.1.5 平方阶O(n^2)
for(int i=1;i<n;i++){for(int j=1;j<n;j++){}
}
1.2.1.1.6 立方阶O(n^3)
for(int i=1;i<n;i++){for(int j=1;j<n;j++){for(int k=1;k<n;k++){}}
}
1.2.1.1.7 K次方阶O(n^k)

k层循环

1.2.1.1.8 指数阶O(2^n)
long aFunc(int n){if(n==1){return 1;}else{return aFunc(n-1)+aFunc(n-2);}
}

1.2.2 空间复杂度

空间复杂度主要指算法计算所占的存储空间,也用O(n)表示

int i=1;

变量i的空间指定为4字节

1.2.2.1 常见的空间复杂度

1.2.2.1.1 O(1)

如冒泡排序的空间复杂度,新产生的变量为常数,并不随n增大而增大

//冒泡排序---升序int changeNum=0;//定义一个用于交换的变量for(int j=0;j<arr.length-1;j++){for(int i=0;i<arr.length-1-j;i++){if(arr[i]>arr[i+1]){changeNum=arr[i+1];arr[i+1]=arr[i];arr[i]=changeNum;}}}
1.2.2.1.2 O(n)

如归并排序的空间复杂度,随着n的规模增大,

1.2.2.1.3 O(n^2)

1.3 常用排序算法

1.3.1 冒泡排序

示意图
冒泡排序
实现代码

//冒泡排序---升序int changeNum=0;//定义一个用于交换的变量for(int j=0;j<arr.length-1;j++){for(int i=0;i<arr.length-1-j;i++){if(arr[i]>arr[i+1]){changeNum=arr[i+1];arr[i+1]=arr[i];arr[i]=changeNum;}}}

1.3.2 选择排序

示意图
选择排序
实现代码

//选择排序---升序int changeNum=0;//定义一个用于交换的变量for(int j=1;j<arr.length;j++){for(int i=0;i<arr.length-1;i++){if(arr[i]>arr[j]){changeNum=arr[i];arr[i]=arr[j];arr[j]=changeNum;}}}

1.3.3 归并排序

归并排序的执行步骤分为两个:递归+合并。为了便于理解,我们先说合并算法再说递归算法。

1.3.3.1 合并排序

合并排序的前提是已经有两个有序的数组,然后将这两个有序数组合并中一一对比后进行排序的算法
图示:
合并排序图示
实现代码:

//合并两个有序数组并生成一个新的有序数组public static int[] merge(int[] arr){//定义一个新数组用来接收合成的数组int[] temp=new int[arr.length];//数组索引的初始化int i=0,k=0,j=arr.length/2;//如果前后两个数组都未遍历结束while(i<arr.length/2 && j<arr.length){temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];}//如果后面的数组遍历结束,但前面的数组还未遍历结束while(i<arr.length/2) temp[k++]=arr[i++];//如果前面的数组遍历结束,但后面的数组还未遍历结束while(j<arr.length) temp[k++]=arr[j++];//返回合并数组return temp;}
1.3.3.2 递归拆分数组

使用递归的方法拆分一个数组至单个元素
图示:
递归拆分数组
实现代码

public static void recursion(int[] arr){//如果数组长度为1,输出该数组(递归终结)if(arr.length==1){System.out.println(Arrays.toString(arr));//或者执行拆分}else{//找到中间值int mid=arr.length/2;//拆分左边数组int[] templ=new int[mid];for(int i=0;i<templ.length;i++){templ[i]=arr[i];}//判断数组长度的奇偶性,如果是奇数,拆分右边的数组长度要比左边数组长度长1位if(arr.length%2!=0){int[] tempr=new int[mid+1];for(int i=0;i<tempr.length;i++){tempr[i]=arr[mid+i];}recursion(templ);recursion(tempr);//如果是偶数,拆分右边的数组长度与左边数组长度长一样}else{int[] tempr=new int[mid];for(int i=0;i<tempr.length;i++){tempr[i]=arr[mid+i];}recursion(templ);recursion(tempr);}}}
1.3.3.3 递归合并排序—归并排序
public static int[] mergeSort(int[] arr){//找到数组的中间值int mid=arr.length/2;//定义两个新数组,分别用来接收拆分数组的左右int[] templ=new int[mid];int[] tempr;//如果数组长度为1,返回该数组(递归边界)if(arr.length==1){return new int[]{arr[arr.length-1]};//或者执行拆分}else{//拆分左边数组for(int i=0;i<templ.length;i++){templ[i]=arr[i];}//判断数组长度的奇偶性,如果是奇数,拆分右边的数组长度要比左边数组长度长1位if(arr.length%2!=0){tempr=new int[mid+1];//如果是偶数,拆分右边的数组长度与左边数组长度长一样}else {tempr = new int[mid];}//拆分右边数组for(int i=0;i<tempr.length;i++){tempr[i]=arr[mid+i];}//左边数组递归mergeSort(templ);//右边数组递归mergeSort(tempr);}//定义一个新数组用来接收合并的数组int[] temp=new int[arr.length];//合并数组时数组索引的初始化int i=0,k=0,j=0,p=0;//如果左右两个数组都未遍历结束while(i<templ.length && j<tempr.length){temp[k++] = templ[i] <= tempr[j] ? templ[i++] : tempr[j++];}//如果右边的数组遍历结束,但左边的数组还未遍历结束while(i<templ.length) temp[k++]=templ[i++];//如果左边的数组遍历结束,但右边的数组还未遍历结束while(j<tempr.length) temp[k++]=tempr[j++];//返回合并数组for(;p<arr.length;p++) arr[p]=temp[p];return arr;}

http://chatgpt.dhexx.cn/article/PlvSehPU.shtml

相关文章

算法学习的一些个人心得

目录 前言正文总结 前言 悟已往之不谏&#xff0c;知来者之可追。 正文 常规的经验贴呢&#xff0c;就是给学弟学妹推荐一些书单&#xff0c;然后写一写自己的刷题经历&#xff0c;最后推荐大家多打比赛&#xff0c;多做项目&#xff0c;多买一些网课。这是比较容易写的。 但…

算法学习指南:什么是算法?

解释算法的实现逻辑就像讲故事一样。算法会在普通的解决方案中引入新颖的思路或进行某种创新。在本文中&#xff0c;我们将讨论一个简单问题的几个解决方案&#xff0c;解释影响算法性能的一些因素。在这个过程中&#xff0c;我将介绍一些用于分析算法性能的技巧。这些技巧与算…

算法学习基础(一)

作为一名普通的二本学校&#xff0c;我在很早之前就有一个目标&#xff0c;那就是大学之后好好找一个软件开发工作。因此学习了很多的编程基础&#xff0c;不过近几天面试发现&#xff0c;技术官总是喜欢问你算法知识。编程语言不断变化&#xff0c;但是很底层的知识与算法密切…

算法学习(一)

算法第四版学习笔记–1.3 Bags, Queues and Stacks 前面120页都是Java基础&#xff0c;建议有Java基础的同学可以直接从120页开始学习&#xff0c;但是这里面的例子有用到algs4这个jar&#xff0c;需要稍微了解一下&#xff0c;影响不大&#xff0c;都是对JDK的一些封装。 In…

算法学习入门

14天阅读挑战赛 *努力是为了不平庸~ 算法学习有些时候是枯燥的&#xff0c;这一次&#xff0c;让我们先人一步&#xff0c;趣学算法&#xff01;欢迎记录下你的那些努力时刻&#xff08;算法学习知识点/算法题解/遇到的算法bug/等等&#xff09;&#xff0c;在分享的同时加深对…

什么是算法?如何学习算法?算法入门的学习路径

何为算法 简单的说,算法就是:解决问题的手段,并且是批量化解决问题的手段。 比如,我们想要从成都去北京,起点就是成都,终点就是北京。如何去?我们就可以称为算法。 因此选择不同的算法,那么虽然终点都是一样,但是性能以及效率就根据算法的优劣而决定的。因此,我们…

如何学习算法?

今天在群里刚好看到有人在讨论算法的问题&#xff0c;刚好自己曾经也有一个算法大神的梦&#xff0c;来说说自己对算法的理解。 算法怎么学&#xff1f;什么样程度才算把算法学透&#xff1f;算法学会了有什么用&#xff1f; 算法的学习是非常重要的&#xff0c;那算法学到什么…

突发!大连理工大学研三学生自杀,遗书曝光,研究生的压力应该谁来化解?...

点击上方“码农突围”&#xff0c;马上关注 这里是码农充电第一站&#xff0c;回复“666”&#xff0c;获取一份专属大礼包真爱&#xff0c;请设置“星标”或点个“在看” 来源&#xff1a;科研干货 10月13日&#xff0c;微博上一个名为“红烧土豆叶”的网友引起广大网友关注&a…

英雄算法学习路线

文章目录 零、自我介绍一、关于拜师二、关于编程语言三、算法学习路线1、算法集训1&#xff09;九日集训2&#xff09;每月算法集训 2、算法专栏3、算法总包 四、英雄算法联盟1、英雄算法联盟是什么&#xff1f;2、如何加入英雄算法联盟&#xff1f;3、为何会有英雄算法联盟&am…

算法如何学习?别想太多,两个字

文章目录 前言一、语言基础1、「 光天化日学C语言 」 二、刷题必读1、「 LeetCode零基础指南 」2、「 九日集训每日打卡 」 三、语言入门1、「 C语言入门100例 」 四、算法入门1、「 算法零基础100讲 」 五、算法进阶1、「 画解数据结构 」2、「 LeetCode算法题集汇总 」3、「 …

YOLOv5剪枝✂️| 模型剪枝实战篇

本篇博文所用代码为开源项目修改得到,且不适合基础太差的同学。 本篇文章主要讲解代码的使用方式,手把手带你实现YOLOv5模型剪枝操作。 文章目录 0. 环境准备1. 使用YOLOv5训练自己的模型2. 对训练好的模型进行稀疏训练3. 对稀疏训练后的模型进行剪枝4. 对剪枝后的网络模型微…

决策树——预剪枝和后剪枝

目录 简析 为什么要剪枝&#xff1f; 剪枝的基本策略 预剪枝 后剪枝 剪枝的优缺点 预剪枝的优缺点 后剪枝的优缺点 实现 数据集 剪枝前 预剪枝 分析 代码 简析 为什么要剪枝&#xff1f; “剪枝”是决策树学习算法对付 “过拟合” 的主要手段 可通过“剪枝”来…

网络剪枝通俗解释

论文链接&#xff1a;Learning Efficient Convolutional Networks through Network Slimming 视频链接&#xff1a;唐宇迪 基本思想 我们在模型生成通道数为[64,128,256,512]的特征图&#xff0c;但是这些特征图不一定都重要&#xff0c;我们希望能够体现特征图的主次之分&…

α、β剪枝法

在讲α、β剪枝法之前&#xff0c;我们先了解一下极大极小值算法&#xff1b;因为α、β剪枝法是为了简化极大极小值的计算而提出的。 极大极小值法 Minimax算法 又名极小化极大算法&#xff0c;是一种找出失败的最大可能性中的最小值的算法&#xff08;即最小化对手的最大得益…

决策树的剪枝

目录 一、为什么要剪枝 二、剪枝的策略 1、预剪枝&#xff08;pre-pruning&#xff09; 2、后剪枝&#xff08;post-pruning&#xff09; 三、代码实现 1、收集、准备数据&#xff1a; 2、分析数据&#xff1a; 3、预剪枝及测试&#xff1a; 4、后剪枝及测试&#xff1…

决策树算法和剪枝原理

决策树算法和剪枝原理 本节我们对决策算法原理做简单的解析&#xff0c;帮助您理清算法思路&#xff0c;温故而知新。 我们知道&#xff0c;决策树算法是一种树形分类结构&#xff0c;要通过这棵树实现样本分类&#xff0c;就要根据 if -else 原理设置判别条件。因此您可以这…

决策树(decision tree)(二)——剪枝

决策树&#xff08;decision tree&#xff09;(二)——剪枝 **注&#xff1a;本博客为周志华《机器学习》读书笔记&#xff0c;虽然有一些自己的理解&#xff0c;但是其中仍然有大量文字摘自周老师的《机器学习》书。 决策树系列博客&#xff1a; 决策树&#xff08;一&#x…

机器学习--决策树二(预剪枝和后剪枝)

一、什么是决策树的剪枝 对比日常生活中&#xff0c;环卫工人在大街上给生长茂密的树进行枝叶的修剪。在机器学习的决策树算法中&#xff0c;有对应的剪枝算法。将比较复杂的决策树&#xff0c;化简为较为简单的版本&#xff0c;并且不损失算法的性能。 二、为什么要剪枝 剪枝…

关于剪枝对象的分类(weights剪枝、神经元剪枝、filters剪枝、layers剪枝、channel剪枝、对channel分组剪枝、Stripe剪枝)

文章目录 剪枝对象分析&#xff1a;1.weights剪枝&#xff1a;2.神经元剪枝&#xff1a;3.Filters剪枝&#xff1a;4.通道剪枝5.Group-wise剪枝6.Stripe剪枝 剪枝对象分析&#xff1a; 剪枝分为结构化剪枝和非结构化剪枝&#xff0c;细化可分为weights剪枝、神经元剪枝、filte…

决策树——剪枝处理

剪枝处理 1&#xff1a;剪枝处理的原因 “剪枝”是决策树学习算法对付“过拟合”的主要手段&#xff0c;因此&#xff0c;可通过“剪枝”来一定程度避免因决策分支过多&#xff0c;以致于把训练集自身的一些特点当做所有数据都具有的一般性质而导致的过拟合 2&#xff1a;剪…