176
社区成员
发帖
与我相关
我的任务
分享《图解算法-使用C语言》这本书如图:

目录
核心思想:将一个难以直接解决的大问题依照相同的概念分割成两个或更多的子问题,以便逐个击破。
主要应用:快速排序法、递归算法、大整数乘法、数字的分类和排序。
优点:可以将原先复杂的问题变成规则更简单、数量更少、速度更快且更容易轻易解决的小问题。
核心思想:如同分治法将复杂问题分解,使其更容易求解。
定义:假如一个函数或子程序是由自身所定义或调用的,就称为递归。(可以简单理解为自己调用自己)
必要条件:一个可以反复执行的递归过程与一个跳出执行过程的窗口。
应用:阶乘函数、堆栈、斐波那契数列
定义:采取在当前状态下最有利或最优化的选择,不断地改进该解答,持续在每一步骤中选择最佳的方法,并且逐步逼近给定的目标,当达到某一步骤不能再继续前进时算法停止,以尽可能快地求得更好的解。
缺点:不能保证求得的最后解是最佳的,容易过早做决定,只能求满足某些约束条件可行解的范围。
应用:求图的最小生成树、最短路径、霍哈夫曼编码
定义:如果一个问题答案与子问题相关,就能将大问题拆解成各个小问题,并且(相较于分治法)可以让每一个子问题的答案被存储起来,以供下次求解时直接取用。
优点:可以减少再次计算的时间,还可以将这些解组合成大问题的解答,故而可以用动态规划解决重复计算的问题。
应用:斐波拉契数列
定义:执行固定次数的循环得到想要的数据。
必要条件:(1)变量初始值;(2)循环条件判断表达式;(3)调整变量增减值。
应用:阶乘
核心思想:将要分析的项目在不遗漏的情况下逐一列举出来,再从所列举的项目中找到自己所需要的目标对象。
定义:(又称穷举法)根据问题要求,逐一列举问题的解答,或者为了便于解决问题,把问题分为不重复、不遗漏的有限种情况,逐一列举各种情况并加以解决,最终达到解决整个问题的目的。
定义:(对于某些问题而言)是一种可以找出所有(或一部分)解的一般性算法,同时避免枚举不正确的数值。
特点:在搜索过程中寻找问题的解,当发现不满足求解条件时,就回溯,尝试别的路径,避免无效搜索。
应用:走迷宫
*关于时间复杂度的计算,本书提及的内容初学者不太适合学习,建议看《算法图解-人民邮电出版社》关于时间复杂度的计算,或者网上自行寻找教程。
| 大O表示法 | 名称 | 说明 |
| O ( 1 ) | 常数时间 | 表示算法的运行时间是一个常数倍 |
|
O ( n ) | 线性时间 | 表示执行的时间会随着数据集合的大小而线性增长 |
| O ( log2 n ) | 次线性时间 | 成长速度比线性时间慢,但比常数时间快 |
| O ( n^2 ) | 平方时间 | 算法的运行会呈二次方的增长 |
| O ( n^3 ) | 立方时间 | 算法的运行会呈三次方的增长 |
| O ( 2^n ) | 指数时间 | 算法的运行时间会呈2的n次方增长 |
| O ( nlog2 n ) | 线性乘对数时间 | 介于线性和二次方增长的中间模式 |
n >= 16时,时间复杂度的优劣关系如下:
O ( 1 ) < O ( log2 n ) < O ( n ) < O ( nlog2 n ) < O ( n^2 ) < O ( n^3 ) < O ( 2^n )
*此处都只是介绍,后续会更新每一项的具体用法。
数据:指的是一种未经处理的原始文字、数字、符号或图形等,一般分为由可用运算符进行运算的数值数据,和其他非数值数据的字符数据。
信息:是利用大量的数据,经过有系统的整理、分析、筛选处理而提炼出来的,且具有参考价格以及提供决策依据的文字、数字、符号或图表。
数据结构:主要表示数据在计算机内存中所存储的位置及其模式。
数据结构通常可以分为以下三种类型:
(1)基本数据类型(又称标量数据类型):每种编程语言都有其独特的基本数据类型。(如C语言的int、float、void等)
(2)结构化数据类型(又称虚拟数据类型):是一种比基本数据类型更高一级的数据类型(如字符串、数组、指针等)
(3)抽象数据类型:比结构化数据类型更高级,是指一个数学模型以及定义在此数学模型上的一组数学运算或操作,在计算机中表示的是一种“信息隐藏” 的程序设计思想以及信息之间某一种特定的关系模式。(如堆栈、队列等)
定义:是一排紧密相邻的可数内存,并提供了一个能够直接访问单一数据内容的计算方法。(结构化数据类型)
可视为一维数组的扩展,都是用于处理数据类型相同的数据,差别只在于维数的声明。参考格式如下:
数据类型 二维数组名 [ 行大小 ] [ 列大小 ]
在存取二维数组的元素时,使用的索引值仍然是从0开始计算。在二维数组设置初始值时,为了方便区分行与列,处理最外层的{ }外,最好以{ }括住每一行元素的初始值,并以“ , ”隔开每个数组元素,参考如下:
数据类型 数组名 [ 行大小 ] [ 列大小 ] = { { 第0行初值 }, { 第1行初值 }, ...,{ 第n行初值 } }
其表示法基本上和二维数组一样,可视为一维数组的延伸,可看作是一个立方体。参考格式如下:
数据类型 二维数组名 [ 行大小 ] [ 列大小 ] [ 高大小 ] = { { { 第0行初值 },
{ 第1行初值 },
...,
{ 第n行初值 } },
{ { 第0行初值 },
{ 第1行初值 },
...,
{ 第n行初值 } },
...
{ { 第0行初值 },
{ 第1行初值 },
...,
{ 第n行初值 } } }
定义:是由许多相同数据类型的数据项按特定顺序排列而成的线性表。
特点:各个数据项在计算机内存中的位置是不连续且随机存放。
优点:数据的插入和删除都相当方便。
缺点:设计数据结构时较为麻烦,且在查找数据时也无法像静态数据(如数组)那样可随机读取数据,必须按序查找到该数据为止。
定义:是一群相同数据形态的组合,所有的动作均在顶端进行,具有“后进先出”的特性。(抽象数据类型)
特性:
(1)只能从堆栈的顶端存取数据。
(2)数据的存取符合“后进先出”的原则。
基本运算:
| 运算 | 说明 |
| create | 创建一个空堆栈 |
| push | 把数据存压入堆栈顶端,并返回新堆栈 |
| pop | 从堆栈顶端弹出数据,并返回新堆栈 |
| empty | 判断堆栈是否为空堆栈,是则返回true,不是则返回false |
| full | 判断堆栈是否已满,是则返回true,不是则返回false |
定义:所有加入与删除的动作都发生在不同的两端,并且符合“先进先出”的原则。(抽象数据类型)
特性:
(1)具有“先进先出”的特性
(2)拥有两种基本操作,即加入和删除
基本运算:
| 运算 | 说明 |
| Create | 建立空队列 |
| Add | 将新数据加入队列的尾端,返回新队列 |
| Delete | 删除队列前端的数据,返回新队列 |
| Front | 返回队列前端的值 |
| Empty | 若队列为空集合,则返回true,否则返回false |
定义:是由一个或一个以上的节点组成的,,每个节点都是一些数据和指针组合而成的记录。
延伸:树可以组成森林,也就是由n个互斥树的集合(n>=0)移去树根形成的。
专有名词简介:
度数:每个节点所有子树的个数。
层数:树的层数。
高度:树的最大层数。
树叶(又称终端节点):度数为0点节点就是树叶。
父节点:与每一个节点连接的上一层节点。
子节点:与每一个节点连接的下一层节点。
祖先:指从树根到该节点路劲上锁包含的节点。
子孙:在该节点往下追溯子树中的任一节点。
兄弟节点:有共同父节点的节点。
非终端节点:树叶以外的节点。
同代:在同一棵树中具有相同层数的节点。
定义:图是由“顶点”和“边”所组成的集合,通常用G = ( V, E )表示,其中V是所有顶点组成的集合,E是所有边组成的集合。
(1)无向图
是一种边没有方向的图,即具有相同边的两个顶点没有次序关系,( V1, V2 )与( V2, V1 )相同。
(2)有向图
是一种每一条边都可使用有序对< V1, V2 >来表示的图,< V1, V2 >和< V2, V1 >是表示两个方向不同的边。
定义:是一种存储记录的连续内存。
遵循原则:
(1)避免碰撞和溢出的发生
(2)哈希函数不宜过于复杂。越容易计算越佳。
(3)尽量把文字的键值转换成数字的键值,以利于哈希函数的运算。
(4)所设计的哈希函数计算得到的值尽量能均匀地分布在每一桶中,不要过于集中在某些桶中,这样既可以降低碰撞又能减少溢出。
专有名词简介:
桶(bucket):哈希表中存储数据的位置,每一个位置对应唯一的地址。
槽(slot):每一个记录中可能包含多个字段,而槽就是桶中的字段。
碰撞(collision):两个不同的数据经过哈希函数运算后对应到相同的地址。
溢出:如果数据经过哈希函数运算后所对应的桶已满,就会使桶发生溢出。
同义词:当两个标识符经过哈希函数运算后所得的数值相同,则这两个标识符相对于当前哈希函数为同义词。
加载密度:标识符的使用数目除以哈希表内槽的总数,即:α(加载密度)= n(标识符的使用数目)/ [ s(每一个桶内的槽数)* b(桶的数目)],α的值越大,表示哈希空间的使用率越高,碰撞或溢出的概率也会越高。
完美哈希:没有碰撞和溢出的哈希函数。