不懂的概念 171030

其实有六成问题都是来自于对过去学过知识的生疏,其他的则是没接触过的新知识。

171030

scanf函数的返回问题:

171022发起。问题来源于在做pta题的时候,系统总是在提交之后提示我“没有处理scanf的返回值”,可是之前其实不知道scanf有返回值。

今天搜了一下,scanf确实有返回值,会返回一个int,表示有多少个变量被成功赋值。

用处的话,感觉可以当做一个检测状态的变量吧。


171107

Trie树问题:

Trie树,也叫字典树,例子如下:根节点不储存字符。思路是:将单词分成字符串,每个结点保存一个字符,从根结点到叶结点,经过的结点构成一个单词。

trie树有助于压缩空间,同时也便于寻找前缀相同的单词。


指针操作数组的问题:

事实证明,我那种out->array可以直接这样使用:out->array[i],也可以*(out->array+i)


171109

辗转相除法的复杂度:

思路一:设更大的数为n,两个数辗转相除一次,必然有一个数减小了一半以上,故为logn。

思路二:辗转相除法的最差情况是斐波那契数列相邻的两项,也就是说Fn%Fn-1 = Fn-2。

二分插入:

是插入法的改进,插入法一般是从最后一个开始向前比较然后插入。二分插入就是用类似二分查找的思想,先跟i/2的元素比较。

Z-Buffer算法:

这个是3D绘制中使用到的算法,具体是用于判断面是否显示,或者说在3D观察视角下哪个点在前哪个点在后。


171119

浙大pta期中问题:

1 next大小写问题;2 二维数组搜索 时间复杂度是N2,相当于N个数中复杂度为N;3 循环队列专指用数组实现的队列



171120

各种树的问题:

二叉搜索树:左儿子小于根结点小于右儿子

平衡二叉搜索树:AVL数,经过调整的二叉搜索树,具体算法Mooc浙大讲过,大概是在家结点中扩展一个单独的域用于记录高度,同时更新高度差。通过这种高度差,分成四类调整整个二叉树,最终将整个二叉树调整为尽量贴近完全二叉树。

AVL树虽然做到了层数最少,搜索效率最大化,但是也面临一个问题,就是维持自身结构的时候貌似很没有效率。之后的几种树都是在这方面努力。

红黑树:不使用“高度-高度差”这种调整准则,而是使用另一个域“红黑色”作为调整准则。这种红黑树高度大于AVL,所以搜索效率略微不如AVL,但是维持成本比AVL树低。据说操作复杂度都是logn。另外标记红黑状态这个域本身可以用1bit的数据长度实现。

(但是这个说法也未必对,下面知乎链接里有个程序员做了测试,优化过的AVL树统计性能还要略优于RBTree)

之后就是引申出来的B树 B+树 还有 Trie树

B树和B+树都是N叉树,每个节点可以有更多的孩子,新的值可以插在已有的节点里,而不需要改变树的高度,从而大量减少重新平衡和数据迁移的次数,这非常适合做数据库索引这种需要持久化在磁盘,同时需要大量查询和插入操作的应用。

https://www.zhihu.com/question/30527705


171122

外排序 胜者树败者树:

当内存空间不足以装下所有数据时,就需要使用外排序。

内排序有许多方法,但是外排序的思想基本就是K路归并。具体做法是,分成内存大小的分块,分块在内存里内部排序,最后输出各自有序的分块;多路归并分块,最后整理成一个有序的大文件。

考虑到硬盘的读取和写入比内存慢得多,外排序的性能衡量指标就是io次数。对于初始m块,k路归并下单个数据的io次数为logm/logk,所以提高k可以有效提高效率。

外排序优化方向:1 增加文件缓冲区,提高io速度;2 将读取、排序、写入分成三个部分进行流水线化(此时排序部分最好别用快排,快排时间不稳定, 容易影响其他部分);3 流水线化就需要将内存分为三个部分,也就是将分块大小进一步缩小;4 最后就是在内存内维持有序串的方法,如下、

胜者树 败者树:

胜者树和败者树是在内存维持有序串的方法。

多路归并一般是将k个文件的最小元素先放到内存中,选出最小后输出,再从刚才输出元素所属的文件中提取一个最小元素放到内存里,然后更新内存中的有序串。

对于胜者树,胜者树有k个叶子结点,每个结点保存第i文件当前最小值。向上的父节点保存两个叶子结点比较大小的胜者的节点序号i。故根节点保存的是当前最小元素的序号。输出时输出当前元素,同时根据根节点i更新叶节点,之后更新胜者树。

败者树原理类似胜者树,不同的是父节点保存的是败者序号,根节点保存的是亚军序号,同时根节点之上还有一个结点单独保存总胜者。

一般比较最小值需要做k-1次比较,败者树和胜者树只需要logk次

败者树相比胜者树的优势在于:重构的时候,败者树的父节点保存的是之前败者的序号,可以直接获取。而胜者树保存的是胜者的需要,还需要一步计算才能获得败者。


171123

下界决策树:

这个名字其实不太对。决策树本身是一个概念,当某个问题的所有解等概率,可以用一个树表示决策过程。树的叶节点是每个解,父节点表示一次决策。这就是决策树。决策树需要构造成完全二叉树,也就说如果有n个叶结点,就表示树的高度是logn。

举个例子,n个数排序,如果不考虑大小的,所有可能情况是n!,将这n!个解放到叶结点,则这棵树的深度为O(nlogn)级。

这个证明过程如下:对于上界,可以将n n-1 n-2都扩大到n,那么就是n!<n^n,也就是上界为nlogn;对于下界,可以将n!序列中不小于n/2的都变成n/2,剩下的舍弃,这样就有n!>(n/2)^(n/2),下界为nlogn。

对于基于比较的排序算法,决策过程可以用决策树表示,则n个数排序,时间复杂度下界的最好情况就是nlogn。

ps 根据如下链接博客,自己理解之后所写:

http://blog.youkuaiyun.com/u012745772/article/details/17467869


171124

进程和线程:

进程是程序的单位,一个程序就是一个或者多个进程,但是一个进程只能是一个程序。cpu处理的单位是进程,一个进程的执行过程在cpu这里是:“读入 处理 写出”。

线程某种程度上可以说是进程的单位,进程包含很多模块,一个模块就是一个线程。线程负责单独的功能,切换的开销比进程小。

这两个文章写的比较好。

http://blog.youkuaiyun.com/Cowena/article/details/47132675

http://blog.youkuaiyun.com/zheng548/article/details/54669908


171125

线索树:

普通二叉树进行遍历时无法容易的获得前驱节点和后继结点。另外普通二叉树的指针域浪费严重,一个n结点的二叉树有2n个指针域,但是因为只有n-1条边,所以有n+1个指针域是浪费的。

针对以上两种情况,提出线索树。核心是:当左儿子或者右儿子为空指针时,左儿子指向前驱,右儿子指向后继。指针域在每个结点上添加了两个布尔数据域,用以判断是指向前驱还是左儿子。这种处理是非递归的,复杂度为n

因为实际先序线索树和后序线索树都不太常用,比如先序线索树不好找前驱,后序线索树不好找后继。所以最常用的还是中序线索树。

【具体实现代码没看】

https://www.cnblogs.com/kavs/p/5002752.html


171126

计数排序:

跟基数排序排序不是一个。原理类似投票,另外要两个N大小的数组。第一个数组用于计数,第二个用于输出。

计数的原理是,比如当前是第i个数,统计原数组中有多少比这个数小的元素的个数,将个数写入计数数组,最后输出数组中元素的下标就是个数。

还有一个解释,设数组中最大的数是K,设置一个大小为K的数组,遍历原数组,将K[i]++,最后倒序输出。

这个排序有局限性,就是只能排序正整数,属于空间换时间的算法。

https://www.cnblogs.com/kaituorensheng/archive/2013/02/23/2923877.html


171127

二叉排序树:

也叫二叉搜索树、二叉查找树,缩写BST。性质为左子树<根节点<右子树,另外子树也是BST。其中序遍历严格递增。


形参的缺省储存类型:

实际问题归属于“储存类型”这个问题。储存类型是指c语言储存变量的类型,变量除了数据类型,还有储存类型。

储存类型包括四种:auto,static,extern和register。其中auto是局部变量的默认类型,static标记静态变量,extern是引用其他文件的变量,register是修饰放在寄存器中的变量(事实上据说现在现在不怎么用这个了,因为cpu处理速度够)。后三者的生存时间都是整个程序。

https://www.nowcoder.com/questionTerminal/a8a664a975494d9a8d7169568b4ddbff?orderByHotValue=1&page=1&onlyReference=false

http://blog.youkuaiyun.com/hjxhjh/article/details/8947397

https://www.cnblogs.com/banana201/archive/2015/10/30/4923101.html


171128

插值搜索、斐波那契搜索:

两种基于二分查找的优化,针对1/2这个比例进行优化。插值搜索使用一个value修改步长,斐波那契则用斐波那契数列修改步长。二者的复杂度虽然也是logn,但是插值在分布平均时优于二分。

斐波那契查找则使用了斐波那契序列fi-2 + fi-1 = fi 这个性质,通过对mid=fi-1的比较,可以将序列分为fi-1 和 fi-2 两个部分。


171129

原地工作:

指的是,无论问题的规模有多大,算法需要的额外空间不变。

buddy内存管理方法,也叫兄弟内存管理方法:

兄弟块指的是,同样大小、地址连续且是同一个大块分出来的两块。

buddy内存法分配出的小块,大小都是2的幂。比如一共1m的内存,可能分成128k 256k 512k 1m。

当需要一个例如100k的内存空间,就先向上扩大到128k,然后查找有没有128k的空间。如果没有就向上找256k,以此类推。如果到1m都没有,那么就作出两个512k空间,将其中一个挂到空内存链表上,另一个继续分割,直到获得128k空闲内存空间。

删除的时候,将当前内存块释放,然后找有没有兄弟空闲空间,如果有就合并然后继续找。

buddy内存算法能一定程度减少浪费(浪费无法避免),linux据说就是用buddy算法管理内存。


171130

数值概率算法:

似乎是用概率的方式,完成不好用表达式进行的计算,比如计算圆周率(向一个装着圆的正方形随机投点),计算积分(同前)

网上博客中,数值概率算法都是在一个大类中讲解,但是这个大类我没太看懂,里面还有比如Monte Carlo算法之类的东西。

又看了一遍,貌似是概率算法这个大类下的,里面包括数值概率算法, 舍伍德算法,蒙特卡洛法和维加斯算法。这几个算法的基础是计算机产生伪随机数。

这个博客有点意思:http://www.wutianqi.com/?page_id=1948


171201

子集树:

如果解决一个问题需要从含有n个元素的集合S中找到满足某种特性的一个子集,那么这个解空间,就被称为子集树。子集树有2^N个叶结点。(区别于排列树,排列树是求n个元素的某种排列,有n!个叶结点。)

子集树和排列树都与回溯法有关,具体的东西估计要仔细的看回溯法。

https://www.cnblogs.com/chinazhangjie/archive/2010/10/22/1858410.html


171206

P问题和NP问题:

P类问题指的是,具有多项式级别速度算法的问题的集合。

对于大规模数据量问题,n!以上的效率是非常低的,一般在多项式级别的速度是可以接受的,比如n nlong n^2之类。

而NP问题,指的是能在多项式级别时间内验证一个解正确性的问题。比如旅行商问题TSP,就是一个NP问题。但是一般认为P!=NP。

归约指的是,比如一个问题A可以用另一个问题B的算法求得,那么A可以归约为B。比如B问题有3个小问题,A问题只有其中的两个,那么解B的算法都可用来解A,只要设定不在A中的那个问题为某个特值即可。

NPC问题:任何NP问题都可以归约到NPC问题。这个解释不太懂,用我的理解或许应该是,无法继续归约的NP问题,就是NPC问题。如果一个NPC问题能在多项式时间内证明,那么任何NPC问题都可以,也就是证明了NP=P。

https://www.cnblogs.com/Gavin_Liu/archive/2011/05/04/2012284.html


171210

常用页面管理算法及相关

在没有内存抽象的时代,进程直接访问物理内存地址,这种情况下是不能多进程的,因为多进程可能导致多个进程同时访问相同的地址,导致错误。

【Q:为啥覆盖了内存数据就会崩溃?还是说这种覆盖是直接把程序本身都覆盖了。】

产生内存抽象之后,内存就有两个寄存器,一个管理首地址,一个管理长度,分别是base和limit。此时操作虚拟内存地址,为多线程实现提供了可能。

虚拟内存的思想是,将内存分为大小相等的块,叫做页。当通过虚拟内存访问页,如果页不存在(称为“缺页中断”),则从硬盘中调入,或者将内存中的无用页抽出再放入。

页面管理算法,就是为了尽量避免缺页中断而提出的算法,主要功能为对于从内存中挑出无用页进行优化选择。

页面管理算法主要包括:

最佳置换:挑最不会被使用的(下次使用时间最远的),是最优情况,但是基本是空想无法实现。

最久不常用:淘汰最近最长时间未被使用的,很难实现。(LRU。least recently used,删除未被使用时间最长的页)

最近不常用:用几个标记,标记页最近是否被访问过、被修改过,优先淘汰没被访问过的(LFU,least frequently used,删除这段时间内访问频率最低的页)

先进先出和改进版先进先出:优先淘汰先进入的,很可能会淘汰正在用的页;改进版类上,加入一个标记记录是否最近访问过,如果有则跳过。先进先出可能出现个叫Belady错误的问题,然而我并不知道这个问题是什么意思。——解释意思:Belady错误是指:分配页面增加,但是缺页中断现象不减少。据说基于堆栈的算法不会出现,但是基于队列的算法,比如fifo就有。

时钟置换:说是即是是改进版的fifo,也会有经常移动页的缺陷。时钟置换是将队首连成一个链,出现缺页时就向前寻找:当找到的页最近访问过,则将访问标记清零,然后继续;如果没被访问过,则挑出。

对了,说是有个“局部性理论”:空间上,最近访问过的页旁边的页是相对更可能在下次被访问的;时间上,最近访问过的页下次更可能被访问。

【opt>lru>clock】

https://www.cnblogs.com/CareySon/archive/2012/04/25/2470063.html

http://blog.youkuaiyun.com/a724888/article/details/70038420

https://www.cnblogs.com/fkissx/p/4712959.html


171213

nat服务

全名叫Network Address Translation,叫网络地址转换服务。用途是,当内网电脑已经有本地ip时还想与外网联系时,可以在外网和内网之间使用nat软件。

只要内网有一个有效的外网ip地址,nat就可以将本地ip转换成外网ip,从而令内网电脑与外网联系。

http://blog.51cto.com/tonyguo/191467


171214

完全二部图:

完全图,指的是图中每个点都与其他点相连的图。

二部图,或者叫二分图,是说图重中的点可以分为两个子集,此时每条边的两个顶点一个在u中一个在v中。

完全二部图:u中每个顶点都与v中顶点相连


180116

修改文件后缀 为什么能直接修改格式:

是我想偏了,windows的机制是,使用一个表把文件格式和默认打开这种格式的程序关联。文件本身都是那种固定编码,修改后缀只是修改要用什么应用打开。看样子,任何应用都可以打开任何文件,只是不对应的文件打开了也用不了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值