那些年程序员学过的算法
突然冒出个想法,把本科阶段的算法做个总结,以后复习的时间也不用胡子眉毛一把抓了
马冬冬
手艺人
展开
-
数据库之关系数据理论
数据库的规范化(上一篇博客有写到)的程度不同,便有了这么多种范式。数据库范式是数据库设计必不可少的知识,没有对范式的理解,就无法设计出高效率、优雅的数据库,甚至设计出错误误的数据库。课本中的定义比较抽象,不太直观,也不易理解,记是肯定记不住的。关系数据库常用范式关系数据库知道了,再来理解范式。范式是关系数据库关系模式规范化的标准,从规范化的宽松到严格,分为不同的范式,通常使用的有第一范式。第...转载 2019-11-23 11:18:42 · 615 阅读 · 0 评论 -
磁盘调度之扫描类算法
1、扫描(SCAN)算法1)进程“饥饿”现象SSTF算法虽然能获得较好的寻道性能,但却可能导致某个进程发生“饥饿”现象。因为只要不断有新进程的请求到达,且其所要访问的磁道与磁头当前所在磁道的距离较近,这种新进程的I/O请求必然优先满足。对SSTF算法略加修改后所形成的SCAN算法,即可防止老进程出现“饥饿”现象。2)SCAN算法该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是...原创 2019-11-17 12:46:02 · 13548 阅读 · 0 评论 -
磁盘调度之最短寻道时间优先
最短寻道时间优先(SSTF,Shortest Seek Time First)该算法选择这样的过程,其要求访问的的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。但这种算法不能保证平均寻道时间最短。下图示出了按SSTF算法进行调度时,各种进程被调度的次序、每次磁头移动的距离,以及9次调度磁头平均移动的距离。...原创 2019-11-17 12:02:00 · 2237 阅读 · 0 评论 -
磁盘调度之先来先服务
先来先服务(FCFS,First Come First Served)这是一种最简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。此算法的优点是公平、简单,且每个进程的请求都能依次地得到处理,不会出现某一进程的请求长期得不到满足的情况。但此算法由于未对寻道进行优化,致使平均寻道时间可能较长。下图示出了有9个进程先后提出磁盘I/O请求时,按FCFS算法进行调度的情况。这里将进程号(请求...原创 2019-11-17 11:56:49 · 2272 阅读 · 0 评论 -
页面置换之Clock置换算法
LRU算法是较好的一种算法,但由于它要求有较多的硬件支持,故在实际应用中,大多采用LRU的近似算法。Clock算法就是用得较多的一种LRU近似算法。1、简单的Clock置换算法当采用简单Clock算法时,只需为每页设置一位访问位,再将内存中的所有页面都通过链接指针链接成一个循环队列。当某页被访问时,其访问位被置1。置换算法在选择一页淘汰时,只需检查页的访问位。如果是0,就选择该页换出;若为1,...原创 2019-11-17 11:41:27 · 11223 阅读 · 0 评论 -
页面置换之最近最久未使用置换算法
LRU(Least Recently Used)置换算法LRU置换算法是选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当须淘汰一个页面时,选择现有页面中其t值最大的,即最近最久未使用的页面予以淘汰。利用LRU算法对上例进行页面置换的结果如图所示。当进程第一次对页面2进行访问时,由于页面7是最近最久未被访问的,故将它置换出去。当...原创 2019-11-17 10:58:54 · 2000 阅读 · 0 评论 -
页面置换算法之最佳置换算法和先进先出置换算法
1.最佳(Optimal)置换算法该算法所选择的淘汰页面,将是以后永不使用的,或许是在最长(未来)时间内不再被访问的页面。采用最佳置换算法,通常可保证获得最低的缺页率。但由于人们目前还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因而该算法是无法实现的,但可以利用该算法去评价其他算法。现举例说明如下。假定系统为某进程分配了三个物理块,并考虑有以下的页面号引用串:...原创 2019-11-17 10:43:54 · 4018 阅读 · 0 评论 -
避免死锁之银行家算法
1. 算法思想银行家算法是为了避免死锁的算法,是Dijkstra的银行家算法。由于该算法用于实现银行系统现金贷款的发放而得名的。为实现银行家算法,系统中必须设置若干数据结构。1) 银行家算法的数据结构a) 可利用资源向量availableb) 最大需求矩阵c) 分配矩阵d) 需求矩阵2) 银行家算法设Requesti 是进程Pi的请求量,如果Requesti[j]=k,表示进程Pi...原创 2019-11-17 10:13:56 · 403 阅读 · 0 评论 -
实时调度算法之最低松弛度优先算法
最低松弛度优先即LLF(Least Laxity First)算法该算法是根据任务紧急(或松弛)的程度,来确定任务的优先级。任务的紧急程度愈高,为该任务所赋予的优先级就愈高,以使之优先执行。例如,一个任务在200ms时必须完成,而它本身所需的运行时间就有100ms,因此,调度程序必须在100ms之前调度执行,该任务的紧急程度(松弛程度)为100ms。又如,另一任务在400ms时必须完成,它本身需...原创 2019-11-17 10:07:58 · 12066 阅读 · 5 评论 -
实时调度算法之EDF算法
最早截止时间优先即EDF(Earliest Deadline First)算法该算法是根据任务的开始截止时间来确定任务的优先级。截止时间愈早,其优先级愈高。该算法要求在系统中保持一个实时任务就绪队列,该队列按各任务截止时间的早晚排序;当然,具有最早截止时间的任务排在队列的最前面。调度程序在选择任务时,总是选择就绪队列中的第一个任务,为之分配处理机,使之投入运行。最早截止时间优先算法既可用于抢占式...原创 2019-11-17 09:23:46 · 23042 阅读 · 4 评论 -
操作系统线程同步之读者-写者问题
读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:(1)允许多个读者同时执行读操作;(2)...原创 2019-11-16 18:58:37 · 946 阅读 · 0 评论 -
操作系统线程同步之哲学家进餐问题
1、问题描述(死锁)五个哲学家,五只筷子,只有获得一双筷子之后才能就餐,就有可能出现这种情况:每个哲学家都获得了一只筷子,卡死在那个地方。2、解决哲学家就餐问题当然后很多方法:(1)有一个服务生来负责避免死锁(2)哲学家在拿筷子的时候,确保左右都有筷子才同时拿起左右两只筷子(3)规定拿筷子的方式:给筷子编号,先拿号码小的筷子3、第二种方式java代码实现:class Chopsti...原创 2019-11-16 18:46:50 · 465 阅读 · 0 评论 -
操作系统线程同步之生产者---消费者问题
生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。wait/notify方法首先,我们搞清楚Thread.sleep()方法和Object.wait()、Object.notify()方法的区别。sleep(...原创 2019-11-16 18:34:00 · 395 阅读 · 0 评论 -
为什么四次握手之后需要等待2MSL
TCP释放过程如下图:为什么A在TIME_WAIT状态必须等待2MSL的时间呢?(1)为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因而使处在LAST_ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后,...原创 2019-11-16 18:00:22 · 734 阅读 · 0 评论 -
TCP和UDP对比
UDP的主要特点是(1)UDP是无连接的(2)UDP使用尽最大努力交付(3)UDP是面向报文的(4)UDP没有拥塞控制(5)UDP支持一对一、一对多、多对一和多对多的交互通信(6)UDP的首部开销小TCP的主要特点是(1)TCP是面向连接的运输层协议(2)每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的(3)TCP提供可靠交付的服务(4)TCP提供全双工通信(...原创 2019-11-16 17:41:56 · 117 阅读 · 0 评论 -
计算机网络之TCP拥塞控制
1.引言 计算机网络中的带宽、交换结点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏。这种情况就叫做拥塞。 拥塞控制就是防止过多的数据注入网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制是一个全局性的过程,和流量控制不同...原创 2019-11-16 12:41:30 · 454 阅读 · 0 评论 -
计算机网络之分组转发算法
算法如下:(1)从数据报的首部提取目的主机的IP地址D,得出目的网络地址为N。(2)若N就是与此路由器直接相连的某个网络地址,则进行直接交付,不需要再经过其他的路由器,直接把数据报交付给目的主机(这里包括把目的主机地址D转换为具体的硬件地址,把数据报封装为MAC帧,再发送此帧);否则就是间接交付,执行(3)。(3)若路由表中有目的地址为D的特定主机路由,则把数据报传送给路由表中所指明的下一条...原创 2019-11-16 12:30:59 · 3411 阅读 · 0 评论 -
各种内部排序方法的比较讨论
排序方法平均时间最坏情况辅助存储简单排序O(n2)O(n2)O(1)快速排序O(nlogn)O(n2)O(logn)堆排序O(nlogn)O(nlogn)O(1)归并排序O(nlogn)O(nlogn)O(n)基数排序O(d(n+rd))O(d(n_rd))O(rd)(1)从平均时间性能而言,快速排序最佳,其所需时...原创 2019-11-16 11:07:27 · 394 阅读 · 0 评论 -
归并排序
归并排序 (merge sort) 是一类与插入排序、交换排序、选择排序不同的另一种排序方法。归并的含义是将两个或两个以上的有序表合并成一个新的有序表。归并排序有多路归并排序、两路归并排序 , 可用于内排序,也可以用于外排序。这里仅对内排序的两路归并方法进行讨论。一、两路归并排序算法思路分而治之(divide - conquer);每个递归过程涉及三个步骤第一, 分解: 把待排序的 n 个元...原创 2019-11-16 10:34:37 · 136 阅读 · 0 评论 -
堆排序
一、堆排序堆排序(Heap Sort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。二、堆1、什么是堆堆是一个树形结构,其实堆的底层是一棵完全二叉树。而完全二叉树是一层一层按照进入的顺序排成的。按照这个特性,我们可以用数组来按照完全二叉树实现堆。2、大顶堆与小顶堆大顶堆原理:根结点(...原创 2019-11-16 10:26:21 · 135 阅读 · 0 评论 -
B-和B+树
B-树是一种平衡的多路查找树,它在文件系统中很有用。一棵m阶的B-树,或为空树,或为满足下列特性的m叉树:(1)树中每个节点至多有m棵子树;(2)若根节点不是叶子节点,则至少有两棵子树;(3)除根之外的所有非终端节点至少有向上取整m/2棵子树(4)所有的非终端节点中包含下列信息数据(n,A0,K1,A1,K2,…,Kn,An)其中:Ki(i=1,…,n)为关键字,且Ki<Ki+1...原创 2019-11-15 21:49:33 · 139 阅读 · 0 评论 -
平衡二叉树
平衡二叉树又称AVL树。它或者是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。若将二叉树上节点的平衡因子定位为该节点的左子树的深度减去它的右子树的深度,则平衡二叉树上所有节点的平衡因子只可能是-1、0、1.只要二叉树上有一个节点的平衡因子的绝对值大于1,则该二叉树就是不平衡的。public class AVL { ...原创 2019-11-15 21:22:05 · 107 阅读 · 0 评论 -
二叉排序树
二叉排序树:或者是一棵空树;或者是具有下列性质的二叉树:(1)若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;(2)若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;(3)它的左、右子树也分别为二叉排序树import java.util.Scanner; /** * 二叉排序树 (binary sort tree) * 对于一个根节点,其左子树上所有节点的...原创 2019-11-15 21:09:52 · 188 阅读 · 0 评论 -
弗洛伊德算法
每一对顶点之间的最短路径/* * floyd最短路径。 * 即,统计图中各个顶点间的最短路径。 * * 参数说明: * path -- 路径。path[i][j]=k表示,"顶点i"到"顶点j"的最短路径会经过顶点k。 * dist -- 长度数组。即,dist[i][j]=sum表示,"顶点i"到"顶点j"的最短路径的长度是sum。 */public void...原创 2019-11-14 22:51:48 · 372 阅读 · 0 评论 -
Dijkstra算法
从某个源点到其余各顶点的最短路径package com.routeSearch.route;public class Dijkstra { private int[] distance; private int[] route; private static int Max = 999; /** * 求顶点begin到顶点i的最小距离。 ...原创 2019-11-14 22:44:35 · 97 阅读 · 0 评论 -
有向图的拓扑排序
什么是拓扑排序?简单地说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。若集合X上的关系R是自反的、反对称的和传递的,则称R是集合X上的偏序关系。设R是集合X上的偏序,如果对每个x,yЄX必有xRy或yRx,则称R是集合X上的全序关系。直观地看,偏序指集合中仅有部分成员之间可比较,而全序指集合中全体成员之间均可比较。import java.util.ArrayLis...原创 2019-11-14 22:21:11 · 221 阅读 · 0 评论 -
最小生成树之kruskal算法
kruskal算法描述:假设连通网N=(V,{E}),则令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{ }),图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点落在T中不同的连通分量上,则将此边加入到T中,否则舍去此边而选择下一条代价最小的边。以此类推,直至T中所有顶点都在同一连通分量上为止。kruskal算法描述如下:package Kruskal;...原创 2019-11-14 22:06:23 · 133 阅读 · 0 评论 -
最小生成树之Prim算法
Prim算法介绍:假设N = (V, {E})是连通网,TE是N上最小生成树中边的集合。算法U={u0}(u0ЄV),TE={}开始,重复执行下述操作:在所有uЄU,vЄV-U的边(u,v)ЄE中找一条代价最小的边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止。此时TE中必有n-1条边,则T=(V,{TE})为N的最小生成树。Prim算法构造最小生成树的过程如下:代码如下:i...原创 2019-11-14 21:52:16 · 280 阅读 · 0 评论 -
递归之汉诺塔
汉诺塔算法描述假设有3个命名为X,Y和Z的塔座,在塔座X上插有n个直径大小各不相同、依小到大编号为1,2,…,n的圆盘。现要求将X轴上的n个圆盘移至塔座Z上并仍按同样顺序叠排,圆盘移动时必须遵循下列规则:每次只能移动一个圆盘圆盘可以插在X,Y和Z中的任一塔座上任何时刻都不能将一个较大的圆盘压在较小的圆盘之上请问怎么移动?代码描述/** * 汉诺塔(唯有递归才...原创 2019-10-23 19:05:07 · 127 阅读 · 0 评论 -
线性链表之一元多项式2
代码实现Java版项的类package demo; //一元多项式的项public class term { //系数 int coef; //指数 int expn; public term() { } public term(int coef, int expn) { this.coef = coef;...原创 2019-10-23 18:46:49 · 300 阅读 · 0 评论 -
线性链表之一元多项式1
算法描述:符号多项式的操作,已经成为表处理的典型用例。在数学上,一个一元多项式Pn(x)P_n(x)Pn(x)可按升幂写成:Pn(x)=p0+p1x+p2x2+...+pnxnP_n(x) =p_{0} + p_1x + p_2x^2 + ... + p_nx^nPn(x)=p0+p1x+p2x2+...+pnxn它由n+1个系数唯一确定。因此,在计算机里,它可用一个线性表PPP...原创 2019-10-23 18:37:56 · 483 阅读 · 0 评论 -
栈和队列之表达式求值
表达式求值算法描述对整数表达式求值. 表达式中可能包含±*/四则运算, 以及括号, 比如:4 + 2 * 3 - 10 / 5, (1+2) * (4 + 5) - (9 / 7)等.算法思路将括号之间的内容当做子表达式求值, 得出子表达式的结果后就可以去掉括号了.使用optr栈存储运算符, opnd栈存储操作数. 解析表达式, 如果得到操作数就存入opnd栈中, 如果得到运算符, 就根...原创 2019-10-23 18:31:06 · 1201 阅读 · 2 评论 -
栈和队列之迷宫求解
迷宫求解算法描述通常用的是“穷举求解”的方法,即从入口出发,顺某一方向向前探索,若能走通,则继续往前走;否则沿原路返回,换一个方向再继续探索,直至所有可能的通路都探索到为止。为了保证在任何位置上都能沿原路退回,显然需要用栈来保存从入口到当前位置的路径。代码实现#include <stdio.h>#include <stdlib.h>#define MaxRow...原创 2019-10-23 17:23:34 · 574 阅读 · 0 评论 -
栈和队列之行编辑程序
行编辑程序算法描述接受用户从终端输入的程序或数据,并存入用户的数据区。由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的。较好的做法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区。允许用户输入出差错,并在发现有误时可以及时更正。例如,当用户发现刚刚键入的一个字符是错的时,可补进一个退格符...原创 2019-10-23 17:04:58 · 259 阅读 · 0 评论 -
栈和队列之括号匹配
括号匹配算法描述检验表达式中括号是否合法代码描述源代码:#include <stdio.h>#include <malloc.h>#include <stdlib.h>//定义一个栈typedef struct Stack{ char *top; char *bottom; int size;}Stack,*PSta...原创 2019-10-23 16:51:35 · 426 阅读 · 0 评论 -
栈和队列之数制转换
算法1:数制转换原创 2019-10-23 16:32:07 · 1779 阅读 · 1 评论 -
数据结构篇
作为计算机领域非常重要的一个方向,我个人认为数据结构是编程领域最有趣味,最有挑战的模块之一。如果学会了各种编程语言的数据结构,就好像拿到了该语言的《九阳真经》,平凡的招式都能演化出很多种变化。所以,本章就介绍数据结构中的各种算法。主要蓝本就是严蔚敏老师的《数据结构》。 首先我们来统一术语,方便沟通使用。数据:客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序...原创 2019-10-23 12:04:51 · 127 阅读 · 0 评论 -
那些年程序员学过的算法
作为一个IT从业者,从本科到现在学习了很多个算法,有ACM竞赛的,数据结构的,操作系统的,计算机网络的,甚至汇编的。本专题就为这些算法做一个总结,每个算法尽可能描述详细,简单。本人会不定期更新,每篇博客可能会引用业界同学们的一部分内容,如有冒犯,请告知。...原创 2019-10-20 18:00:09 · 131 阅读 · 0 评论