北航专业课简要笔记

北航991考纲的简要笔记。

概述

  1. 数据的逻辑结构:数据元素之间具有的逻辑关系,线性结构,非线性结构等.
  2. 数据的存储结构:具有某种逻辑结构的数据在计算机存储器中的存储方式,顺序,链式,索引,散列等.
  3. 算法的定义:是用来解决某个特定课题的指令的集合
  4. 算法的性质:输入,输出,有穷性,确定性,有效性
  5. 算法分析:为了改进算法,而对算法质量优劣的评价.时间复杂度,空间复杂度
  6. 一个算法中的语句执行次数称为语句频度或时间频度,记为$T(n)$。若有某个辅助函数$f(n)$,使得当n趋近于无穷大时,$\frac{T(n)}{f(n)}$的极限值为不等于零的常数,则称$f(n)$是$T(n)$的同数量级函数。记作$T(n)=O(f(n))$,称$O(f(n))$为算法的渐进时间复杂度,简称时间复杂度。基本上$f(n)$为$T(n)$的最高阶项部分。$O(\log_{2}n)<O(n)<O(n\log_{2}n)<O(n\^2)<O(n\^3)<(2\^n)<O(n!)$

线性表

  1. 线性关系:除了第一个元素与最后一个元素,序列中任何一个元素有且仅有一个直接前驱元素, 有且仅有一个直接后继元素。数据元素之间的先后顺序为“一对一”的关系.
  2. 线性表定义:数据元素之间具有的逻辑关系为线性关系的数据元素集合称为线性表,n为线性表的长度,长度为0的线性表称为空表
  3. 线性表基本操作:建表;求长度;检索第i个数据元素;根据某个数据项查找在表中的位置;在i个位置存入新数据;在第i个位置插入新数据;删除第i个数据;按照某数据项排序;销毁;复制;合并;分解
  4. 线性表顺序构造原理:用一组地址连续的存储单元依次存储线性表的数据元素,数据元素之间的逻辑关系通过数据元素的存储位置直接反映;所谓一个元素的 是指该元素占用的k个(连续的)存储单元的第一个单元的地址
  5. 线性表特点:构造原理简单,存储开销小;存储空间事先分配,一片连续空间,插入删除效率低
  6. 线性链表构造原理:用一组地址任意的存储单元(连续的或不连续的)依次存储表中各个数据元素, 数据元素之间的逻辑关系通过指针间接地反映出来。
  7. 线性链表特点:存储空间动态分配,不需要连续空间,插入,删除效率高;需要设置结点域,查找定位效率低

堆栈与队列

  1. 堆栈定义:堆栈是一种只允许在表的一端进行插入操作和删除操作的线性表。允许操作的一端称为栈顶,栈顶元素的位置由一个称为栈顶指针的变量给出。当表中没有元素时,称之为空栈.后进先出
  2. 堆栈基本操作:入栈;出栈;堆栈是否为空;堆栈是否满;检索当前栈顶元素
  3. 堆栈顺序存储构造原理:描述堆栈的顺序存储结构最简单的方法是利用一维数组 STACK[0..M–1 ] 来表示,同时定义一个整型变量( 不妨取名为top) 给出栈顶元素的位置
  4. 堆栈链式存储构造原理:链接堆栈就是用一个线性链表来实现一个堆栈结构, 同时设置一个指针变量( 这里不妨仍用top表示)指出当前栈顶元素所在链结点的位置。栈为空时,有top=NULL
  5. 队列定义:是一种只允许在表的一端进行插入操作,而在表的另一端进行删除操作的线性表。允许插入的一端称为队尾,队尾元素的位置由rear指出; 允许删除的一端称为队头, 队头元素的位置由front指出.先进先出
  6. 队列基本操作:入队,出队,队列是否为空,检索当前队头元素,创建一个空队
  7. 队列顺序存储构造原理:在实际程序设计过程中,通常借助一个一维数组QUEUE[0..M–1]来描述队列的顺序存储结构,同时,设置两个变量 front与rear分别指出当前队头元素与队尾元素的位置
  8. 队列链式存储构造原理:队列的链式存储结构是用一个线性链表表示一个队列,指针front与rear分别指向实际队头元素与实际队尾元素所在的链结点
  9. 循环队列:把队列(数组)设想成头尾相连的循环表,使得数组前部由于删除操作而导致的无用空间尽可能得到重复利用,这样的队列称为循环队列

树与二叉树

  1. 树的概念:是由n>=0个结点组成的有穷集合(不妨用符号D表示)以及结点之间关系组成的集合构成的结构,记为T。当n=0时,称T为空树
  2. 树的特点:有且仅有一个结点没有前驱结点,该结点为树的根结点;除了根结点外,每个结点有且仅有一个直接前驱结点;包括根结点在内,每个结点可以有多个后继结点
  3. 名词术语:
    • 结点的度:该结点拥有子树的数目
    • 树的度:树中结点度的最大值
    • 叶结点:度为0的结点(终端结点)
    • 分支结点:度不为0的结点(非终端结点)
    • 树的层次:根结点为第一层,若某结点在第i 层,则其孩子结点(若存在)为第i+1层
    • 树的深度:树中结点所处的最大层次数(高度)
    • 路径:对于树中任意两个结点di和dj,若在树中存在一个结点序列d1,d2, … di, …,dj,使得di是di+1的双亲(1≤i<j),则称该结点序列是从di到dj的一条路径。路径的长度为j-1
    • 祖先和子孙:若树中结点d到ds存在一条路径,则称d是ds的祖先,ds是d的子孙
    • 森林:m>=0 棵不相交的树组成的树的集合
    • 树的有序性:若树中结点的子树的相对位置不能随意改变, 则称该树为有序树,否则称该树为无序树
  4. 二叉树定义:是n>=0个结点的有穷集合D与D上关系的集合R构成的结构,记为T。当n=0时,称T为空二叉树;否则,它为包含了个根结点以及两棵不相交的、分别称之为左子树与右子树的二叉树。
  5. 满二叉树:若一棵二叉树中的结点,或者为叶结点, 或者具有两棵非空子树,并且叶结点都集中在二叉树的最下面一层.这样的二叉树为满二叉树
  6. 完全二叉树:若一棵二叉树中只有最下面两层的结点的度可以小于2,并且最下面一层的结点(叶结点)都依次排列在该层从左至右的位置上.这样的二叉树为完全二叉树
  7. 二叉树性质:
    • 具有n个结点的非空二叉树共有n–1个分支
    • 非空二叉树的第i 层最多有2^{i–1}个结点(i>=1)
    • 深度为h 的非空二叉树最多有2^{h}–1个结点
    • 若非空二叉树有n0个叶结点,有n2个度为2的结点,则 n0=n2+1
    • 具有n个结点的非空完全二叉树的深度为$h=\left \lfloor log_{2}n \right \rfloor+1$
    • 若对具有n个结点的完全二叉树按照层次从上到下,每层从左到右的顺序进行编号, 则编号为i的结点具有以下性质:
      • 当i=1,则编号为i的结点为二叉树的根结点;若i>1,则编号为i 的结点的双亲的编号为$\left \lfloor i/2 \right \rfloor$
      • 若2i>n,则编号为i 的结点无左子树;若2i<=n,则编号为i的结点的左孩子的编号为2i
      • 若2i+1>n,则编号为i 的结点无右子树;若2i+1<=n,则编号为i的结点的右孩子的编号为2i+1
  8. 二叉树顺序存储结构:根据完全二叉树的性质6 ,对于深度为h的完全二叉树, 将树中所有结点的数据信息按照编号的顺序依次存储到一维数组BT[0..2^{h}-2]中,由于编号与数组下标一一对应,该数组就是该完全二叉树的顺序存储结构.一般二叉树,则添加不存在的虚结点,使其成为完全二叉树
  9. 二叉树链式存储结构:data 为数据域;lchild 与rchild分别为指向左、右子树的指针域;也可以加一个指向双亲结点的parent指针
  10. 二叉树前序遍历:若被遍历的二叉树非空, 则1. 访问根结点;2. 以前序遍历原则遍历根结点的左子树;3. 以前序遍历原则遍历根结点的右子树.中序后序类似
  11. 二叉树按层次遍历:若被遍历的二叉树非空,则按照层次从上到下,每一层从左到右依次访问结点,通过队列来遍历
  12. 递归遍历算法

    void  PREORDER(BTREE T) {  
        if(T!=NULL){
            PREORDER(T->lchild);
            VISIT(T);     // 访问T指结点
            PREORDER(T->rchild);
        }
    }
    
  13. 非递归遍历(堆栈)

    void  INORDER(BTREE T) {
        BTREE STACK[M], p=T;
        int top=-1;
        if(T!=NULL) 
            do {
                while(p!=NULL){
                STACK[++top]=p;
                p=p->lchild;
                }
                p=STACK[top– ];
                VISIT(p);
                p=p->rchild;
            }while(!(p==NULL && top==-1));
    }
    
  14. 已知前序序列和中序序列,恢复二叉树:在前序序列中确定根; 到中序序列中分左右
  15. 已知中序序列和后序序列,恢复二叉树:在后序序列中确定根; 到中序序列中分左右
  16. 线索二叉树:利用链结点的空的左指针域存放该结点的直接前驱的地址,空的右指针域存放该结点直接后继的地址;而非空的指域仍然存放结点的左孩子或右孩子的地址
  17. 二叉排序树:二叉排序树或者为空二叉树, 或者为具有以下性质的二叉树:
    • 若根结点的左子树不空, 则左子树上所有结点的值都小于根结点的值;
    • 若根结点的右子树不空, 则右子树上所有结点的值都大于或等于根结点的值; 每一棵子树分别也是二叉排序树
  18. 二叉树的建立:若二叉树为空, 则ki 作为该二叉树的根结点;若二叉树非空, 则将ki 与该二叉树的根结点的值进行比较, 若ki小于根结点的值,则将ki插入到根结点的左子树中;否则,将ki插入到根结点的右子树中。将ki插入到左子树或者右子树中仍然遵循上述原则
  19. 二叉排序树查找:递归,非递归
    • 若二叉排序树为空,则查找失败,查找结束。
    • 若二叉排序树非空,则将被查找元素与二叉排序树的根结点的值进行比较
    • 若等于根结点的值,则查找成功,结束;
    • 若小于根结点的值,则到根结点的左子树中重复上述查找过程;
    • 若大于根结点的值,则到根结点的右子树中重复上述查找过程;
    • 直到查找成功或者失败
  20. 平均查找长度ASL:确定一个元素在树中位置所需要进行的元素间的比较次数的期望值(平均值),$\sum 第i个元素的概率*第i个元素需要进行的元素之间的比较次数$

  1. 图的定义:图是由顶点的非空有穷集合与顶点之间关系(边或弧)的集合构成的结构, 通常表示为G =(V, E)其中, V 为顶点集合, E 为关系(边或弧)的集合
  2. 名词解释:
    • 顶点的度:依附于顶点vi的边的数目,记为TD(vi);OD(vi)出度,ID(vi)入度
    • 路径和路径长度:顶点vx到vy之间有路径P(vx,vy)的充分必要条件为: 存在顶点序列 vx, vi1,vi2, …, vim, vy,并且序列中相邻两个顶点构成的顶点偶对分别为图中的一条边;出发点与止点相同的路径称为回路或环;顶点序列中顶点不重复出现的路径称为简单路径。不带权的图的路径长度是指路径上所经过的边的数目,带权图的路径长度是指路径上经过的边上的权值之和
    • 子图:对于图G=(V,E) 与 G´=(V´,E´), 若有$V´\subseteq V$, $E´\subseteq E$,则称G´为G的个子图
    • 图的连通性:
      • 无向图的连通性:无向图中顶点vi 到vj 有路径,则称顶点vi 与vj 是连通的。若无向图中任意两个顶点都连通, 则称该无向图是连通的
      • 有向图的连通性:若有向图中顶点vi 到vj 有路径,并且顶点vj到vi 也有路径,则称顶点vi 与vj 是连通的。若有向图中任意两个顶点都连通,则称该有向图是强连通的
    • 生成树:包含具有n个顶点的连通图G的全部n个顶点,仅包含其n-1条边的极小连通子图称为G的个生成树
  3. 邻接矩阵存储方法:定义一个二维数组A[0..n-1,0..n-1]存放图中所有顶点之间关系的信息(该数组被称为邻接矩阵)
  4. 邻接表存储方式:建立n个线性链表存储该图,每个链表存储由该结点出发的没一条边(通过存储某个其他结点来代表边).
    • 无向图的第i个链表中边结点个数是第i个顶点度数。
    • 有向图的第i个链表中边结点个数是第i个顶点的出度。
    • 无向图的边结点个数一定为偶数;边结点个数为奇数的图一定是有向图
  5. 图的深度优先遍历:从图中某个指定的顶点v出发,先访问顶点v,然后从顶点v未被访问过的一个邻接点出发,继续进行深度优先遍历,直到图中与v相通的所有顶点都被访问;若此时图中还有未被访问过的顶点, 则从另一个未被访问过的顶点出发重复上述过程,直到遍历全图
  6. 图的广度优先遍历:从图中某个指定的顶点v出发,先访问顶点v,然后依次访问顶点v的各个未被访问过的邻接点,然后又从这些邻接点出发, 按照同样的规则访问它们的那些未被访问过的邻接点,如此下去,直到图中与v 相通的所有顶点都被访问; 若此时图中还有未被访问过的顶点, 则从另一个未被访问过的顶点出发重复上述过程, 直到遍历全图
  7. 最小生成树:带权连通图中,总的权值之和最小的带权生成树为最小生成树。最小生成树也称最小代价生成树,或最小花费生成树
    • 只能利用图中的边来构造最小生成树;
    • 只能使用、且仅能使用图中的n-1条边来连接图中的n个顶点;
    • 不能使用图中产生回路的边
  8. prim最小生成树:依次在G中选择条一个顶点仅在V中,另一个顶点在U中,并且权值最小的边加入集合TE,同时将该边仅在V 中的那个顶点加入集合U.重复上述过程n–1次,使得U=V,此时T为G的最小生成树
  9. kruskal最小生成树:从G中选择一条当前未选择过的、且边上的权值最小的边加入TE,若加入TE后使得T未产生回路,则本次选择有效,如使得T产生回路,则本次选择无效,放弃本次选择的边。重复上述选择过程直到TE中包含了G的n-1条边,此时的T为G的最小生成树
  10. 最短路径:
    • 确定dist、s、path 三个数组的初值。
    • 利用s数组与dist 数组在那些尚未找到最短路径的顶点中确定一个与源点v最近的顶点u,并置s[u]为1,同时将顶点u加入path[u]。
    • 根据顶点u修改源点到所有尚未找到最短路径的顶点的路径长度。
      • 将源点v到顶点u的(最短)路径长度分别加到源点v通过顶点u可以直接到达、且尚未找到最短路径那些的顶点的路径长度上。若加后的长度小于原来v 到某顶点r的路径长度,则用加后的长度替换原来的长度,否则,不作替换。
      • 若替换,将源点v 到顶点u 的路径(最短路径)上经过的所有顶点替换path[r]。
    • 重复上述过程的第2至第3步n–1 次
  11. AVO网:以顶点表示活动,以有向边表示活动之间的优先关系的有向图称为顶点表示活动的网(Activity On Vertex Network),简称AOV网
  12. 拓扑排序:检测工程能否正常进行,首先要判断对应的AOV网中是否存在回路,达到该目的最有效的方法之一是对AOV网构造其顶点的拓扑序列,即对AOV网进行拓扑排序.由某个集合上的一个偏序得到该集合上的一个全序的操作称为拓扑排序
    • 从AOV网中任意选择个没有前驱的顶点;
    • 从AOV网中去掉该顶点以及以该顶点为出发点的所有边;
    • 重复上述过程,直到AOV网中的所有顶点都被去掉,或者AOV网中还有顶点,但不存在入度为0 的顶点,前者说明AOV网中无回路,后者说明AOV网中存在回路
  13. AOE网:AOE(Activity On Edge)网为一个带权的有向无环图,其中,以顶点表示事件,有向边表示活动,边上的权值表示活动持续的时间。
  14. 关键路径定义:从源点到终点的路径中具有最大长度的路径为关键路径;关键路径上的活动称为关键活动
  15. 关键路径特点:
    • 关键路径的长度(路径上的边的权值之和)为完成整个工程所需要的最短时间。
    • 关键路径的长度变化(即任意关键活动的权值变化)将影响整个工程的进度,而其他非关键活动在一定范围内的变化不会影响工期
  16. 求关键活动:若l[i] (最晚开始时间)–e[i] (最早开始时间)=0,则说明活动ai 为一个关键活动
    • 计算事件k的最早发生时间ee[k]:事件k的最早发生时间决定了由事件k出发的所有活动的最早开始时间;该时间是指从源点到顶点(事件)k的最大路径长度:ee[0]= 0,所有前驱事件ee[j]+<j,k>权的最大值
    • 计算事件k的最晚发生时间le[k]:le[n-1] =ee[n-1],所有后驱事件le[j]-<j,k>权的最小值
    • 计算活动 i 的最早开始时间e[i]:e[i] =ee[k],活动i在时间k之后
    • 计算活动 i 的最晚开始时间l[i]:le[j]-<k,j>的权,活动i的前驱后驱事件k,j
    • 求出关键活动与关键路径:l[i] = e[i]即为关键活动

文件和查找

  1. 顺序查找:从文件的第一个记录开始,将用户给出的关键字值与当前被查找记录的关键字值进行比较,若匹配,则查找成功,给出被查到的记录在文件中的位置,查找结束。若所有n 个记录的关键字值都已比较,不存在与用户要查的关键字值匹配的记录,则查找失败,给出信息0 ASL平均查找长度:比较次数的均值,$\frac{n+1}{2}$ 算法的时间复杂度为O(n)
  2. 二分查找法:将要查找的关键字值与当前查找范围内位置居中的记录的关键字的值进行比较。若匹配,则查找成功,给出被查到记录在文件中的位置,查找结束。若要查找的关键字值小于位置居中的记录的关键字值,则到当前查找范围的前半部分重复上述查找过程,否则,到当前查找范围的后半部分重复上述查找过程,直到查找成功或者失败。若查找失败,则给出信息0 若把当前查找范围内居中的记录的位置作为根结点,前半部分与后半部分的记录的位置分别构成根结点的左子树与右子树,则由此得到一棵称为“判定树”的二叉树,利用它来描述折半查找的过程 $ASL \approx \log_{2}(n+1) – 1$ 算法的时间复杂度:$O(\log_{2}n)$
  3. m阶B-树:
    • 每个分支结点最多有m棵子树(即最多有m-1个关键字值)
    • 每个分支结点最少有m/2棵子树
    • 根结点最少有2棵子树
    • 所有“叶结点”都在同一层上
  4. B-树的查找:首先将给定的关键字k在B-树的根结点的关键字集合中采用顺序查找发或者折半查找发进行查找,若有k=keyi, 则查找成功,根据相应的指针取得记录.否则,若k < keyi,则在指针pi-1所指的结点中重复上述查找过程,直到在某结点中查找成功,或者有pi-1=NULL,查找失败
  5. B-树的插入:若将k插入到某结点后使得该结点中关键字值数目超过m-1时,则要以该结点位置居中的那个关键字值为界将该结点一分为二,产生一个新结点,并把位置居中的那个关键字值插入到双亲结点中;如双亲结点也出现上述情况,则需要再次进行分裂.最坏情况下,需要一直分裂到根结点,以致于使得B-树的深度加1
  6. B+树:
    • 每个分支结点最多有m 棵子树;
    • 除根结点外,每个分支结点最少有$/frac{m}{2}棵子树;
    • 根结点最少有两棵子树(除非根为叶结点结点,此时B+树只有一个结点);
    • 具有n 棵子树的结点中一定有n 个关键字
    • 叶结点中存放记录的关键字以及指向记录的指针,或者数据分块后每块的最大关键字值及指向该块的指针,并且叶结点按关键字值的大小顺序链接成线性链表
    • 所有分支结点可以看成是索引的索引,结点中仅包含它的各个孩子结点中最大(或最小)关键字值和指向孩子结点的指针
  7. B-和B+树区别:
    • B-树的每个分支结点中含有该结点中关键字值的个数,B+树没有
    • B-树的每个分支结点中含有指向关键字值对应记录的指针,而B+树只有叶结点有指向关键字值对应记录的指针
    • B-树只有一个指向根结点的入口, 而B+树的叶结点被链接成为一个不等长的链表, 因此,B+树有两个入口,一个指向根结点,另一个指向最左边的叶结点(即最小关键字所在的叶结点)
  8. Hash基本概念:其中,k 为记录的关键字,H(k)称为散列函数,或哈希(Hash)函数,或杂凑函数。函数值A为k对应的记录在文件中位置
  9. 散列冲突:对于不同的关键字ki与kj,经过散列得到相同的散列地址,即有H(ki) =H(kj)这种现象称为散列冲突
  10. Hash文件:根据构造的散列函数与处理冲突的方法将一组关键字映射到一个有限的连续地址集合上,并以关键字在该集合中的“象”作为记录的存储位置,按照这种方法组织起来件称为散列文件,或哈希文件,或称杂凑文件;建立件的过程称为哈希造表或者散列,得到的存储位置称为散列地址或者杂凑地址
  11. 散列函数的构造:
    • 直接定址法:一般形式H(k)=ak+b
    • 数字分析法:n个d位数的关键字由r个不同的符号组成,把均匀分布的某s位作为散列地址
    • 平方取中法:关键字平方后取中间几位
    • 叠加法:把较长的关键字分割成相等的几部分,再叠加后得到散列地址,最后一位对齐,s形折叠
    • 基数转换法:数制基数改变,也就是改变进制
    • 除留余数法:H(k) =k MOD p,p为小于地址范围的素数
  12. 处理冲突方法:所谓处理冲突,是在发生冲突时,为冲突的元素找到另一个散列地址以存放该元素。如果找到的地址仍然发生冲突,则继续为发生冲突的这个元素寻找另一个地址,直到不再发生冲突
    • 开放地址法:散列表中空地址向处理冲突开放Di = ( H(k) +di) MOD m i=1, 2, 3, …. . di为地址增量,有三种策略:di=1,2,3…,线性探测再散列;di=1\^2,-1^2…,二次探测再散列;di=伪随机序列,伪随机探测再散列
    • 再散列法:Di =Hi(k),发生冲突后使用第i个哈希函数再散列
    • 链地址法:将所有散列地址相同的记录链接成一个线性链表。若散列范围为[0..m-1],则定义指针数组bucket[0..m-1]分别存放m个链表的头指针

内排序

  1. 插入排序:将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止 n-1躺排序;稳定;时间复杂度为$O(n/^2)$ 折半插入排序是从中间开始比较,可以减少比较次数,但是不能减少移动次数
  2. 选择排序法:在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止 n-1躺排序;不稳定;时间复杂度为$O(n/^2)$
  3. 冒泡排序法:第i趟序对序列的前n-i+1个元素从第一个元素开始依次作如下操作:相邻的两个元素比较大小,若前者大于后者,则两个元素交换位置,否则不交换位置 可能少于n-1躺排序;稳定;时间复杂度为$O(n/^2)$
  4. 快速排序:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。此时基准元素在其排好序后的正确位置然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。 可能少于n-1躺排序;不稳定;时间复杂度为$O(n\log_{2}n)$
  5. 堆积排序:第i趟排序将序列的前n-i+1个元素组成的子序列转换为一个堆积,然后将堆积的第一个元素与堆积的最后那个元素交换位置 堆积定义:堆积是一棵完全二叉树,二叉树中任何一个分支结点的值都大于或者等于它的孩子结点的值,并且每一棵子树也满足堆积的特性 n-1躺排序;不稳定;时间复杂度为$O(n\log_{2}n)$
  6. 二路归并排序:将两个位置相邻、并且各自按值有序的子序列合并为一个按值有序的子序列的过程称为二路归并 第i趟排序将序列的$\left \lfloor \frac{n}{2\^{(i-1)}} \right \rfloor$个长度为$2\^{(i-1)}$的按值有序的子序列依次两两合并为 $\left \lfloor \frac{n}{2\^i} \right \rfloor$个长度为$2\^i$的按值有序的子序列 $\left \lceil log_{2}n \right \rceil$躺排序;稳定;时间复杂度为$O(n\log_{2}n)$

C语言

  1. FILE类型指针:FILE *fp; fp是一个指向FILE类型结构体的指针变量。可以使fp指向某一个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该文件。如果有n个文件,一般应设n个指针变量,使它们分别指向n个文件,以实现对文件的访问
  2. 文件的关闭与打开: FILE *fp; fp=fopen(文件名,使用文件方式); fclose(fp);
  3. 文件使用方式: “r” (只读)为输入打开一个文本文件 “w” (只写)为输出打开一个文本文件 “a” (追加)向文本文件尾增加数据 “rb” (只读)为输入打开一个二进制文件 “wb” (只写)为输出打开一个二进制文件 “ab“ (追加)向二进制文件尾增加数据 “r+“ (读写)为读/写打开一个文本文件 “w+” (读写)为读/写建立一个新的文本文件 “a+” (读写)为读/写打开一个文本文件 “rb+“ (读写)为读/写打开一个二进制文件 “wb+“ (读写)为读/写建立一个新的二进制文件 “ab+” (读写)为读/写打开一个二进制文件
  4. ANSI C提供一个feof()函数来判断文件是否真的结束。如果是文件结束,函数feof(fp)的值为1(真);否则为0(假)。以上也适用于文本文件的读取;ferror(fp),返回0为出错
  5. 文件的读写:

    char fgets(char * s, int n,FILE *stream); int fputs(char *s, FILE *stream) int fgetc(FILE *stream) int fputc (char c, File *fp) size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) size_t fwrite(const void buffer, size_t size, size_t count, FILE* stream) int fprintf (FILE* stream, const charformat, [argument]) int fscanf(FILEstream,constchar*format,[argument…])

  6. 文件的定位:

    void rewind(FILE *stream),内部位置指针重新指向流的开头 int fseek(FILE *stream, long offset, int fromwhere),以fromwhere为基准偏移 long ftell(FILE *stream),得到当前位置相对于文件首偏移字节数

odroid搭建Android实验环境过程

Published on September 18, 2018

Java并发编程知识总结

Published on August 26, 2018