您的位置:首页 > 理论基础 > 数据结构算法

数据结构知识点复习

2015-08-05 23:28 357 查看
一、综述:

数据结构作为软件开发的必须基础,不仅实用,一般找工作时也常常考到。因此写篇文章,梳理一下数据结构这个知识点的基本框架与结构。

程序设计=数据结构+算法

数据结构:存在特定关系的数据元素的集合

逻辑结构包含:集合结构、线性结构、树结构和图结构;物理结构包括顺序存储于链式存储;

算法特点:输入输出、有穷性、确定性、可行性;算法设计要求:正确性、可读性、健壮性、效率高与存储量低。

算法时间复杂度:是执行此次数的函数;

二、基本数据结构:

1.数组:连续存储的一段内存地址,数组名称代表首地址,数组的总内存长度由元素的个数与元素的类型决定。一般数组定义时必须定义其长度与类型,同时最好初始化。

c语言数组:属于顺序存储,需要定义长度。如果对数据长度变化,使用时采用动态数组进行内存的分配:如int *p=new int
; 释放:delete [] p;p=null;

vector:c++里的一种顺序存储的容器模板,使用与数组类似,由于是模板类,包含大量的造作方法与操作成员;

当往容器中存放的元素大于容器本身所保留的空间后,vector会释放当前的内存,并开辟一块更长的内存地址,来存放要存入的元素。

优点:方便进行元素的查找与修改;使用方便;

缺点:不利于插入与删除元素,每次删除一个元素之后,后面的元素都需要向前移动,开销太大。

2.链表:存储元素的内存地址是非连续的,采用指针指向下一个元素的地址。

链表插入:对于单链表与双向链表,操作方式不同,单链表只需要将插入位置前一元素的指向指针指向要插入的元素,要插入的元素指针指向下一个位置;

链表删除:与具体的链表有关,让删除节点的前一元素的指向指针指向当前节点的下一个元素即可;此外还有静态链表,由数组实现链表;

单链表:c++中为slist;

双向链表:c++为queue;双向链表可以双向进行元素查找、删除、插入操作。不过操作相比较复杂。

环形链表::c++为list

也称为循环链表;将链表最后一个元素的指向指针指向第一个元素;此时如果第一个元素的指向指针指向它自己,那就是空链表。c++中list好像就是循环链表。

3.栈:c++为stack

一种数据结构,具有先进入后出来的操作,即元素只能从一端进入与删除操作,这个入口称为栈顶;可以通过顺序存储结构实现,也可以通过链式存储结构实现;在实际应用中较为广泛。如递归过程与求后缀表达式。

程序栈区:由编译器自动分配与释放,主要保存函数的局部变量,参数等。栈的内存是有限的,一般1MB到2MB,过大的栈区申请将会出错。申请速度较快。

4.队列:c++为queue

具有先进先出,后进后出的特点,即队列的队头只能进入,队尾只能出队。实现形式包括顺序存储与链式存储两种形式,对于链式存储,可看着只能在链表的头部插入元素,尾部删除元素。

双端队列:即队列不区分正反,两边都具有插入与出队的功能,不过出队与入队的操作不能在同一端进行。

变种:包含所谓的出队受限的双端队列和入队受限的双端队列,即双端队列中的某一端,出队或入队的功能失效。

优先队列:此队列带有排序功能,入队的元素默认会进行排序,出队的元素是队列中最大的那个。

5.字符串:有0个或多个字符组成的有限序列;c++中为string

string字符串与c语言中的字符串数组相比,string中的字符个数就是包含的字符个数,而字符串数组则要在尾部加‘\0’,要多一个字符。

string中的存储方式可以为顺序存储于链式存储,顺序存储所占内存小,性能好,链式存储则方便进行删除、插入操作,c++中应该是顺序存储吧,没查到。

字符串匹配:硬匹配,即依次比较两个字符串的字符是否相等,若不相等,从下一个元素起继续循环匹配。

改进的算法:KMP算法。若匹配失败不用每次从下一个元素开始,而是根据匹配字符的个数,调到特定位置,再继续匹配。

6.树:属于非线性存储结构,一棵树有一个根节点,一个节点可以有多个子树。,子树之间不能连接。

树的深度:即树的最大层数;树结构表示方法:可以采用单链表,多重链表,用以表示节点指向的多个孩子节点。

节点的度:即孩子节点的个数;叶子节点:没有孩子节点的节点。

二叉树:所有的节点要么为空,要么包含两个或一个孩子节点,就为二叉树。具体又分为斜二叉树(所有的节点都只有左子树为孩子节点)、满二叉树(如果节点存在子节点,左右节点都必须存在,同时所有的叶子节点都在同一层)、完全二叉树(相比满二叉树,所有的叶子节点都在一层,某个节点可以一个孩子节点,但必须是其同辈的先编号的节点都有两个节点,且此孩子为为左子树)

性质:i层最多2^(i-1)个节点,深度为k的二叉树节点个数最多为2^K-1,有n个节点的完全二叉树,深度为[log2(N)]+1;对于一个二叉树,终端节点数为n0,度为2的节点数为n2,则n0=n2+1;对于完全二叉树,对对于节点i,父节点为[i/2],对于节点为i,一般左节点为2i,右节点为2i+1;

遍历方式:包括前序遍历、中序遍历、后序遍历。关键在于根节点的遍历顺序。

森林:由树转换为二叉树:连接兄弟节点,并删除根节点与第一个节点之外的连线,然后旋转;由森林转换二叉树:先将森林转换为二叉树,在分别由中间向两边接根节点。

应用:霍夫曼树

二叉排序树:

二叉堆:

程序堆区:一块可以使用的内存区,由程序员进行申请与释放,内存不是连续的,内存大小与计算机虚拟内存有关,申请读取慢,容易产生内存碎片。

7.图:元素之间的关系由一对一变为一对多。有顶点和边组成,G(v,e)

边无方向,称为无向图,边有方向,称为有向图,边带权值,称为网。

对于无向图,边数为各定点度之和的一半。对于有向图,边数为个顶点入度或出度的总和。

连通图:图中各顶点可以通过边到达任何一个顶点。对于有向图:两个定点之间一定存在通路。极小生成树:N个顶点由n-1条边连起来即可形成连通图。

存储结构:邻接矩阵(以矩阵的方式几下元素之间的两两关系,比较耗内存,不过容易实现),邻接表(类似链表的方式,记录下每个元素之间的连接关系,实现比较麻烦,不过省内存)十字链表(不是很懂,比较麻烦)边集数组。

图的遍历:主要分为深度优先(DFS,沿着深度方向,遍历,直到最深的节点,然后返回上一层,寻找没遍历的路线继续搜索,)与广度优先(BFS,将图变化一种形式,然后开始搜索当前节点下一层的所有点,都遍历后,开始继续下移一层,遍历所有的点。)

最小生成树:对于网,以n-1条边将N个节点连起来,使得边上的权值之和最小。基本算法:Prim普里姆算法,Kruskal克鲁斯卡尔算法;

最短路线算法:对于网,找到从一个节点到另一个节点的一系列路径,使得经过的边的权值之和最小。基本算法:Dijstra迪杰斯特拉算法,Fiold弗洛伊德算法。

拓扑排序与关键路径算法,还未看。

三、查找

查找表:表示要查找的元素的集合。具体的形式如同一张excel;与数据库中表的概念相同。

关键字:可以当做表头,即每一项的各个属性,其中对这个记录具有唯一性的关键字(属性)称为主关键字,一般是记录的序号,这个是唯一的,其他的是次关键字。

静态查找:(1)查询:看有没有(返回bool类型)(2)检索:查看某项的特定属性,一般要返回的。

动态查找:在表中查找元素后,可以进行插入、删除等操作。需要专门用于插入、删除的数据结构(如二叉排序树)。

顺序查找:采用逐个遍历比较的方式,速度慢。

有序表查找:往往采用半折查找法,(二分法),算法复杂度为O(log(n))。对其改进体现在中间位置的选择,可以根据当前键值与区间的比例进行差值。

此外就是斐波那契查找法,对中间位置改用斐波那契数列的方式得到。

线性索引查找:即数据集此时是无需的,这种现实中比较常见,通过索引技术将关键字与记录相关联起来。

(1)稠密索引:通过索引表(包括关键字与地址指针的一个数组),查询对应的实际记录。

(2)分块索引:把数据分成若干块,形成快内无序,块间有序。同时对于块间,后面的快的最小关键字要大于前面块的最大关键字。然后对所有的块建立索引表,表中每项包含所指向的块的首地址,块中的元素,以及最大关键字等。

(3)倒排索引:对内容建立一个表,并指出包含此内容的元素记录编号。如如单词和文章编号。

二叉排序树:属于一种二叉树结构,方便进行查找、删除与插入操作。对于每个非叶子节点:左子树小于根节点,右子树均大于根节点。关于插入操作,还是比较方便的,先定位到要插入的节点,如果当前位置的节点是叶子节点,直接在这个节点后面生产叶子节点即可;如果是非叶子节点,先先当前节点改为要插入的节点,然后将这个节点的子节点作为插入元素的子节点。

关于删除。相对来说比较麻烦,删除目标节点后,要在目标节点的子节点和孙子节点里找一个合适的元素,来作为此位置的代替者。

平衡为二叉树:二叉树在构建的过程中,会出现左右深度不一致的情况,而平衡二叉树的定义则是左右子树的高度差最多为1,就是平衡因子,即-1或0或1。因此在实现平衡二叉树的过程中,需要不断的计算当前的树是否满足平衡二叉树的定义,如果一个节点的平衡因子不满足要求,如大于1,需要对这个节点以及子节点进行顺时针旋转,如果平痕因子小于零,则进行逆时针旋转。具体还是比较麻烦的。

多路查找树(B树):

(1)2-3树:对于一个树结构,其节点要么没孩子,要么有2个孩子(2节点)或3个孩子(3节点),称为2-3树。2节点只有一个元素和两个孩子,3节点有2个元素和3个孩子。主要包括插入与删除操作,在这个过程总一定要是每个结点都满足2-3树的定义。具体的操作还是挺抽象的。

(2)2-3-4树:与2-3树类似,即每个结点多了一个4节点,包括3个元素和4个孩子。

(3)B树:对于每个结点,要么没孩子节点,要么至少有2个子树,每个结点有K-1个元素和k个孩子。且所有的叶子都位于同一层。

(4)B+树:进行了改进,使得每个叶子节点都有一个指向下一个叶子节点的指针。具体还是蛮复杂的,没多看。

散列查找(哈希表)

即存储位置是关键字的函数,通过对关键字的变换得到具体的存储位置。 存储位置=f(Key) ,这个f称为散列函数,即哈希函数。通过散列表可以存储记录的地址,但是当两个关键字相同时,地址会冲突。

为此提出了各种散列函数构造方法,如(1)直接定址法,f(x)-ax+b.(2)数字分析法 (3)平均取中法(4)折叠法(5)除留余数法(6)随机数法

对于地址冲突的问题,采用开放定址法,再散列函数法,链地址法、公共溢出法等。

四、排序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: