• 读<算法图解><笔记摘录>


    从很多途径当中,看到过这本书的知识点,是一本很有趣的算法入门书籍,最近花费了几天的时间将其阅读完,总想着总结一下这本书的算法知识点,分享给大家,也让自己掌握地更加踏实一点.

    算法:一组完成任何任务的指令

    算法这玩意,在保证满足条件,并且不浪费内存的情况下,要尽可能速度更快,这就是我们要使用和选择算法的原因.
    在这本书当中称为运行时间,在下面每一种算法的过程当中都尽可能会涉及到.

    二分查找在这里插入图片描述

    二分查找的对象是一组有序的数组,记住必须是有序的
    在这组数组当中定义定义索引0是low,而索引(数组最大索引)为high
    当low<=high的时候,mid=(low+high)/2
    这里一看上面书籍就写错了
    如果说中间索引对应的数值刚好等于我们要查找的数字
    则直接返回中间索引数值就好了
    否则判断中间索引对应的数值和我们要查找数字的大小关系
    如果大于,则high=mid-1,相当于我们搜索low到mid-1这个范围
    如果小于,则low=mid+1,相当于我们搜索mid+1到high这个范围
    继续返回上面的while,迭代就行
    如果运行结束,数组当中没有任何数值等于我们要查找的数值
    则返回None
    运行时间:
    在这里插入图片描述
    线性时间描述为O(n)
    二分查找的运行时间描述为O(logn)
    //O(n*logn)这样的算法包括快速排序—一种较快的排序算法
    //O(sqrt(n)),这样的算法包括将介绍的选择排序----一种速度较慢的排序算法
    O(n!)这样的算法包括将介绍的旅行商的解方案—一种速度非常慢的算法<不建议去看和使用>—正常情况下用不到的
    ex:大O表示法是一种特殊的表示法,指出了算法的速度有多快.
    图例如下:
    在这里插入图片描述
    把纵坐标想成时间,去看这几个图就行了

    选择排序

    需要将数据存储到内存时,你请求计算机提供存储空间,计算机给你一个存储地址。需要存储多项数据时,有两种基本方式——数组和链表。

    ex:数组的读取速度很快,但是链表的插入和删除速度很快.
    ex:在同一个数组当中,所有元素的类型都必须是相同的

    使用数组意味着事项在内存当中都是相互连接的,或者说紧靠在一起的
    同时数组的好处在于可以挑选出其中的任何一个事项目,例如a[1]或者a[10],可以直接输出.
    但数组的插入和删除是相当麻烦的,例如一个a[5]的数组,存储有5个数据,如果删除掉开头或者结尾的数据,还比较简单,但是如果删除掉中间的数据,例如a[3],就需要将原来的a[4]和a[5]同时提前,插入同样复杂.

    而链表中的元素可以存储在内存的任何敌方,不需要相互连接或者紧靠,但链表的每个元素都存储了下一个元素的地址
    链表无法像数组那样可以直接挑选出,其中任何一个事项的数据,必须从头开始串联,一直到所寻找的数据为止.
    链表的插入和删除相对简单,例如5个数据,我需要删除第3个数据,则只需要使得第二个数据的下一个地址为第四个数据.原来的第三个数据自动删除

    选择排序:
    在这里插入图片描述
    就是数组从头到尾,依次比较大小,每次都找出数组当中最大或者最小的数据放在数组的一端进行存储,直到全部循环完毕.
    如果是二维数组,是不是让我们想起来了冒泡法:

        //采用冒泡排序法
        for(j=1;j
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    递归

    递归总而言之就是一种分而治之的策略
    盒子里面找盒子,直到找到盒子里面的钥匙为止.
    或者说递归指的就是调用自己的函数
    在这里插入图片描述
    在这里插入图片描述
    第一种方案是递归,而第二种方案则是循环.
    ex:使用循环的性能更好,但是如果使用递归,程序更加容易理解.
    递归函数当中有两个条件,一个是基线条件,一个是递归条件,递归条件很容易理解,就是持续循环,那什么时候判断循环结束呢?这个就叫做基线条件
    ex:调用栈
    举例说明栈这个基本概念:一叠便条要简单很多,插入的待办事项放在清单的最前面;读取待办事项时,你只读取最上面的那个,并将其删除.也就是先进后出.
    因此这个代办事项清单只有两种操作:压入(插入)和弹出(删除并读取)
    在这里插入图片描述
    ex:调用栈,每个函数都需要占用一定的内存,这将导致运行速度变慢.可以转换为循环重新编写代码.或者使用尾递归<这里不做说明>

    快速排序

    一种优雅的排序算法

    //第一种方法,采用快速排序的方法
    
    int cmp_int(const void* _a,const void* _b)
    {
        int* a=(int*)_a; //强制类型转换
        int* b=(int*)_b;
        return *a - *b; //从小到大进行排序,升序,如果是降序,则修改为*b - *a;
    }
        qsort(a,n,sizeof(a[0]),cmp_int);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    是一种分开来治理的算法,可以直接使用
    在这里插入图片描述

    散列表

    简单说,就是存储数组索引的一组代号
    散列表非常适合于防止重复
    思考一下,投票的时候,我们无法控制每个人只投了一票,所以我们可以采用散列表将每个人的姓名进行存储,如果出现重复的则进行条件处理.
    例如:
    在这里插入图片描述
    上图如果无法理解,想一想手机的通讯录,里面有联系人和电话号码.我们不可能记住每一个人的电话号码,但是我们知道要给谁打电话,而通讯录里面的用户名就是散列表
    在这里插入图片描述
    要注意使用散列表的时候,尽可能避免冲突和保持性能:
    1.较低的填装因子<=0.7
    在这里插入图片描述
    2.良好的散列函数

    广度优先搜索

    BFS算法:适合回答"到X的最短路径是什么,或者说到X是否存在路径"这样的问题

    在这里插入图片描述
    从起点出发,一步可以到达的地方进行存储
    二步可以到达的地方进行存储
    三步
    四步
    一直到"n步"数组当中存在有终点,则找到了从起点到终点最短路径为n

    ex:队列,不同于栈,队列是一种先进先出的结构<入队和出队>
    在这里插入图片描述
    在这里插入图片描述
    注意此处是先把第一关系的循环完,然后再执行第二关系循环.
    ex:一个人可能即是a的朋友又是b的朋友,那么我们将产生重复,为避免这种情况,我们需要调用一个检查函数,如果已经执行过,则进行标记.
    在这里插入图片描述
    运行时间:,广度优先搜索的运行时间为O(人数 + 边数),这通常写作O(V + E),其中V为顶点(vertice)数,E为边数。
    无法往后指的图叫做树,例如族谱
    在这里插入图片描述

    狄克斯特拉<后续我将提供一道QT,供大家理解>

    找到加权图中前往X的最短路径
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    如果有负权边,就不能使用狄克斯特拉算法。
    在包含负权边的图中,要找出最短路径,可使用另一种算法——贝尔曼–福德算法

    贪婪算法

    NP完全问题,每一步直接找到最小的或者最大的,然后加起来就是全部最小的或者最大的
    局部全部都小构成了全局尽可能小

    动态规划

    把原来数组和所要求的结果,构成一个新的数组,称为dp数组,然后找到最后一行或者第一行当中数据的最优解,则是我们要寻找的数据.

    K最近邻算法

    找案例A距离或者关系最近的另一个案例B,则B的特征可以代表案例A的特征.

  • 相关阅读:
    【HCIP】路由策略、策略路由
    web系统安全设计原则
    协程设计原理
    Java日期类TemporalAdjuster使用说明
    Android通过RecyclerView实现手风琴效果
    神经网络模型的基本原理,神经网络模型是干嘛的
    数字图像处理实验(一)|图像的基本操作和基本统计指标计算
    image process那个项目的图片上色问题 第二版再说吧 这个是一个可行的方案 cv.histogram 的颜色问题
    【10】leetcode note
    SpringBoot读取.yml配置文件最常见的两种方式-源码及其在nacos的应用
  • 原文地址:https://blog.csdn.net/Lukegood/article/details/128156021