数据结构算法实现及解析
A. 计算机考研:数据结构常用算法解析(8)
第九章 查找
查找分成静态查找和动态查找,静态查找只是找,返回查找位置。而动态查找则不同,若查找成功,返回位置,若查找不成功,则要返回新记录的插入位置。也就是说,静态查找不改变查找表,而动态查找则会有插入操作,会改变查找表的。
不同的查找所采用的存储结构也不同,静态查找采用顺序表,而动态查找由于经常变动,所以用二叉排序树,二叉平衡树、B-和B+。
静态查找有,顺序查找,折半查找,分块查找(索引顺序查找)
顺序查找(Sequential Search)是最简单的一种查找方法。
算法思路
设给定值为k,在表(R1 R2……Rn)中,从Rn即最后一个元素开始,查找key=k的记录。若存在一个记录Ri(l≤i≤n)的key为k,则查找成功,返回记录序号i;否则,查找失败,返回0。
算法描述
int sqsearch(sqlist r,keytype k) //对表r顺序查找的算法//
{ int i;
r.data[0].key=k; //k存入监视哨//
i=r.len; //取表长//
while(r.data[i].key!=k)
i--; //顺序查找//
return(i);
}
算法用了一点技巧:先将k存入监视哨,若对某个i(≠0)有r.data[i].key=k,则查找成功,返回i;若i从n递减到1都无记录的key为k,i再减1为0时,必有r.data[0].key=k,说明查找失败,返回i=0。
平均查找成功长度ASL= ,而查找失败时,查找次数等于n+l。
折半查找算法及分析
当记录的key按关系≤或≥有序时,不管是递增的还是递减的,只要有序且采用顺序存储。
算法描述
int Binsearch(sqlist r,keytype k) //对有序表r折半查找的算法//
{ int low,high,mid;
low=1;high=r.len; //上下界初值//
while(low<=high) //表空间存在时//
{ mid=(low+high)/2; //求当前mid//
if (k==r.data[mid].key)
return(mid); //查找成功,返回mid//
if (k
high=mid-1; //调整上界,向左部查找//
else
low=mid+1; //调整下界,向右部查找//
}
return(0); //low>high,查找失败//
}
判定树:用来描述二分查找过程的二叉树。n个结点的判定树的深度和n个结点的完全二叉树深度相同= 。但判断树不一定是完全二叉树,但他的叶子结点所在层次之差不超过1。所以,折半查找在查找成功时和给定值进行比较的关键字个数至多为
ASL=
分块查找算法及分析
分块查找(Blocking Search),又称索引顺序查找(Indexed Sequential Search),是顺序查找方法的一种改进,目的也是为了提高查找效率。
1.分块
设记录表长为n,将表的n个记录分成b= 个块,每块s个记录(最后一块记录数可以少于s个),即:
且表分块有序,即第i(1≤i≤b-1)块所有记录的key小于第i+1块中记录的key,但块内记录可以无序。
2.建立索引
每块对应一索引项:
KeymaxLink
其中Keymax为该块内记录的最大key;link为该块第一记录的序号(或指针)。
3.算法思路 分块索引查找分两步进行:
(1)由索引表确定待查找记录所在的块;(可以折半查找也可顺序因为索引表有序)
(2)在块内顺序查找。(只能用顺序查找,块内是无序的)
考研有疑问、不知道如何总结考研考点内容、不清楚考研报名当地政策,点击底部咨询官网,免费领取复习资料:https://www.87dh.com/xl/
B. python数据结构与算法-哈希map的实现及原理
1-collections.MutableMapping
1.1 概念:这是什么?
大家可能想知道这一串英文是什么意思?其实只需要了解在collections库当中有一个非常重要的抽象基类MutableMappin
g,专门用于实现map的一个非常有价值的工具。后边我们会用到它。
2-我们的map基类
2.1 实现这个类
这个基类其实也就是确定了键值对的属性,并且存储了基本的比较方法。它的对象就是一个键值对咯。这个很好理解。有点类似object的感觉。
3-通过map基类实现的无序映射
给大家看一个上边的例子,这个例子来源于网络,自己改了改,能用,更加详细而已,凑合看.
4-Python哈希表的实现的基类
4.1 咱有话直说:上才(代)艺(码)
如果还不知道哈希表概念的同xio,请参考 python进阶之数据结构与算法–中级-哈希表(小白piao分享) 。废话不多说,咱们撸代码:
OK了,基本的哈希表就实现了,其实仔细想想很容易,但是自己要能实现还是要理解哈希表的本质哦,外加一定量的练习才可以熟练掌握,练习的目的就是为了熟练而已。
5-分离链表实现的具体哈希map类
说明:这玩意只是一种降低冲突的手段,上一节提过,降低冲突最好的地方是发生在元组进入桶的时候,所以想必大家猜到了,接下来的分离链表也就是为了self._bucket_xxxxxxx系列方法做准备。这里之所以在上边使用@abstractmethod就是为了继承实现,目的可以实现多种将冲突的哈希表。分离链表的概念上一节也有的。
“见码入面”(借鉴:见字如面这个电视节目,有兴趣可以看看,还不错的):
6-用线性探测处理冲突的哈希map类
这种方式的好处不需要再去借助其他额外的赋值结构来表示桶。结构更加简单。不会再像上一种方法还要让桶是一个UnsortedTableMap的对象。
代码如下:
C. 计算机考研:数据结构常用算法解析(7)
第七章:
对于无向图,e的范围是:
数据结构中所讨论的图都是简单图,任意两结点间不会有双重的边。
对于有向图,e的范围是:
图的各种存储结构
邻接矩阵很方便访问任意两点的边,但是不方便计算其邻接点。在深度和广度遍历中广泛的需要求某点的邻接点。所以邻接矩阵只在Floyed和Prim和Dijstra中采用。
邻接表能很方便的求某顶点的邻接点,索引对于与遍历有关的算法大多都采用邻接表。如深度、广度、拓扑排序、关键路径。但他也有不足的地方,就是不方便求入度或是那些薯早握点可以到他的操作。所以有人引进逆邻接表。最后人们把这两种表结合到一起就是十字链表和邻接多重表。一个是存储有向图,另一个是存储无向图。
在十字链睁历表和邻接多重表很方便求邻接点的操作和对应的逆操作。所以实际应用中,凡是能用邻接表实现的一定能用十字链表和邻接多重表实现。并且它们的存储效率更高。
1.邻接矩阵(有向图和无向图和网)又称为数组表示法
typedef struct
{ vextype vexs[maxn]; ∥顶点存储空间∥
adjtype A[maxn][maxn]; ∥邻接矩阵∥
int vexnum,arcnum; //图的顶点数和边数
GraphKind Kind; //图的类型
} mgraph;
2.邻接表(有向图和无向图和网)
typedef struct node ∥边
{ int adj; int w; ∥邻接点、权∥
struct node *next; ∥指向下一弧或边∥
}linknode;
typedef struct ∥顶点类型∥
{ vtype data; ∥顶点值域∥
linknode *farc; ∥指向与本顶点关联的第一条弧或边∥
}Vnode;
typedef struct
{
Vnode G[maxn]; ∥顶点表∥
int vexnum,arcnum;
GraphKind kind;
}ALGraph;
adjvexnextarcinfo
边结点
datafirstarc
顶点结点
3.十字链表(有向图和有向网)
headvextaivexhlinktlinkinfo
边结点
datafirstinfirstout
顶点结点
4.邻接多重表(无向图)
markivexjvexilinkjlinkinfo
边结点
datafirstedge
顶点结点
有向无环图(DAG):是描述含有公共子式的表达式的有效工具。二叉树也能表示表达式,但是利用有向无环图可以实现对相同子式的共享,从而节省存储空间。
顶点的度:
无向图:某顶点V的度记为D(V),代表与V相关联的边的条数
有向图:顶点V的度D(V)=ID(V)+OD(V)
强连通分量:在有向图中,若图中任意两顶点间都存在路径,则称其是强连通图。图中极大 强连通子图称之为强连通分量
“极大”在这里指的是:往一个连通分量中再加入顶点和边,就构不成原图中的一个 连通子图,即连通分量是一个最大集的连通子图。有向图的连通就是指该有向图是强连通的。
考研有疑问、不知道如何总结考研考点内容、不清楚数庆考研报名当地政策,点击底部咨询官网,免费领取复习资料:https://www.87dh.com/xl/
D. 计算机考研:数据结构常用算法解析(1)
数据结构是计算机考研408计算机学科专业基础综合的重要组成部分,考生需要认真复习,尤其是对于数据结构中一些常用的算法问题,考生一定要弄懂弄会,理解的去掌握。猎考考研就带大家一一梳理这些知识点。
第一章
◆ 数据:指能够被计算机识别、存储和加工处理的信息载体。
◆ 数据元素:就是数据的基本单位,在某些情况下,数据元素也称为元素、结点、顶点、记录。数据元素有时可以由若干数据项组成。
◆ 数据类型:是一个值的集合以及在这些值上定义的一组操作的总称。
在高级语言程序中又分为:非结构的原子类型和结构类型
◆抽象数据类型(ADT):是指一个数学模型以及定义在该模型上的一组操作。
一个抽象的数据类型的软件模块通常包含定义和表示和实现
用三元组(D,S,P):数据对象、数据关系、基本操作
◆ 数据结构:指的是数据之间的相互关系,即数据的组织形式。一般包括三个方面的内容:
数据的逻辑结构、存储结构和数据的运算。
◆ 逻辑结构:指各数据元素之间的逻辑关系。
◆ 存储结构:就是数据的逻辑结构用计算机语言的实现。
◆ 线性结构:数据逻辑结构中的一类,它的特征是若结构为非空集,则该结构有且只有一个开始结点和一个终端结点,并且所有结点都最多只有一个直接前趋和一个直接后继。线性表就是一个典型的线性结构。
◆ 非线性结构:数据逻辑结构中的另一大类,它的逻辑特征是一个结点可能有多个直接前趋和直接后继。
常用的存储表示方法有四种:
◆ 顺序存储方法:它是把逻辑上相邻的结点存储在物理位置相邻的存储单元里,结点间的
逻辑关系由存储单元的邻接关系来体现。由此得到的存储表示称为顺序存储结构。
◆ 链接存储方法:它不要求逻辑上相邻的结点在物理位置上亦相邻,结点间的逻辑关系是
由附加的指针字段表示的。由此得到的存储表示称为链式存储结构。
◆ 索引存储方法:除建立存储结点信息外,还建立附加的索引表来标识结点的地址。
◆ 散列存储方法:就是根据结点的关键字直接计算出该结点的存储地址。
渐近时间复杂度的表示法T(n)=O(f(n)),这里的"O"是数学符号,它的严格定义是"若T(n)和f(n)是定义在正整数集合上的两个函数,则T(n)=O(f(n))表示存在正的常数C和n0 ,使得当n≥n0时都满足0≤T(n)≤C·f(n)。"用容易理解的话说就是这两个函数当整型自变量n趋向于无穷大时,两者的比值是一个不等于0的常数。这么一来,就好计算了吧。
求某一算法的时间复杂度是关于N的统计,下面的例子很有反面意义
x=91; y=100;
while(y>0)
if(x>100)
{x=x-10;y--;}
else x++;
◆ T(n)=O(1)
◇ 这个程序看起来有点吓人,总共循环运行了1000次,但是我们看到n没有? 没。
◇ 这段程序的运行是和n无关的,就算它再循环一万年,我们也不管他,只是一个常数阶的函数。
考研有疑问、不知道如何总结考研考点内容、不清楚考研报名当地政策,点击底部咨询官网,免费领取复习资料:https://www.87dh.com/xl/