查找:
顺序查找(数组):按照存储位置从头开始比对查找
折半查找:数据排好序,通过多次取中位数进行比较来进行查找
散列查找:通过散列函数计算出存储位置进行查找。散列函数:存储位置 = f(key)
散列查找基本思想:
散列技术分为:存储技术和查找技术 ,散列技术是面向查找的存储结构,记录之间不存在关联关系,只与关键字有关。不具备很多常用数据结构的能力
散列技术不擅长的领域:
关键字对应很多记录时;范围查找;想获得记录排序;类似最大、最小、均方差等统计值也计算不了
实际应用:多种存储与查找技术相结合,DBMS
核心是散列函数,散列函数设计规则:计算简单(查找效率高)、散列地址分布均与(冲突尽可能少)
散列函数构造方法:
直接定址法:f(key) = a * key + b(a,b为常熟)
优点:简单均与、不会产生冲突;缺点:事先知道关键字分布特征,适合查找效率较小且连续
数字分析法:适合关键字位数比较大,事先知道关键字分布且若干位分布均与
平方取中法:适合不知道关键字分布,且位数不大的情况。位数太大超出整数表达范围,涉及大数运算,查找效率低
折叠法:顺向叠加和S型叠加,适合不知道关键字分布,且位数较多的情况
除留取余法(最常用的散列函数构造方法):f(key) = key mod p (p<=m)
关键:选择合适的p,否则容易产生同义词
p的取值:通常小于p或等于表长m的最大质数,不包含小于20质因子的合数
随机数法:f(key) = random(key),rand函数是伪随机函数,只要随机种子一样随机函数生成数据也一样
散列地址冲突解决方案:
开放地址法(最常用、最有效的方法):f(key) = (f(key i) + di ) mod 12 (di = 1,2,3...)
涉及线性探测和二次探测
思想:一旦发生冲突就寻找下一个空散列地址,并存储
再散列函数法:fi(key) = Rhi(key) (i = 1,2 ...,k)
思想:一旦发生冲突就尝试下一个散列函数,可将所有hash函数构造法相结合;缺点:计算开销大
链地址法:类似图的邻接表。消除冲突地址(效率较高),实现相对复杂
公共区溢出法:用基本表存储数据,当发生冲突时,就把冲突的数据放在溢出表中挨个存取。比较适合冲突数据较少的情况
散列表查找实现
散列表初始化
散列函数定义
插入关键字
查找关键字
散列表的装填因子:填入表中记录个数/散列表长
不同查找算法平均查找长度
图的基本概念和相关术语:
图记为G(V,E) ,V表示顶点集合,E表示边。当边为空时,图依然存在,只有点没有变
有向图:图中每条边都有方向
无向图:每条边都无方向
完全图:任意两个顶点都有一条边相连
若n个顶点的无向图有n(n-1)/2条边,称为无向完全图;若n个顶点的有向图有n(n-1)条边称为有向完全图。
稀疏图:边较少的图,通常边数<<n**2
稠密图:边很多的图,无向图中边数接近n(n-1)/2,有向图中边数接近n(n-1)
子图:顶点和边都属于原图
带权图:边上带权的图。网络=带权图
连通图:无向图中一个顶点到另一个顶点有路径,则称为连通的。如果图中任意顶点之间都有联通则称为连通图
强连通图:有向图中两个顶点之间都存在一条从vi到vj和从vj到vi的路,则称为强连通图。非强连通图的极大强连通子图称为强连通分量
有向边(u,v)叫弧,u叫弧头、v叫弧尾,u,v称为邻接点
度:顶点与它相关联的条数
有向图中,度分为入度和出度:入度顶点作为终点的有向边条数,出度顶点作为始点的有向边条数
生成树:极小连通子图,包含途中全部顶点,但是只有n-1条边;如果在生成树上添加一条边必构成一个环,若图中有n个顶点,却少于n-1条边,必为非连通图
生成森林:若干生成树构成,含全部顶点,但构成这些树的边是最少的
路径:从一个顶点到另一个顶点之间经过的顶点序列
路径长度:
无向图的路径长度是路径上面边的条数,有向图的路径长度是路径上面权的和
简单路径:路径上的顶点不重复
回路:路径上第一个顶点到最后一个顶点重合称为环或着回路
图的存储结构为链式存储(可用多重链表,邻接表、邻接多重表、十字链表),无顺序存储但可用数组描述元素间的关系
邻接矩阵(数组)表示法:
邻接矩阵表示法
例
有向图
有向图分析
带权图邻接矩阵
邻接矩阵优缺点
邻接矩阵算法实现
邻接矩阵算法实现
临界点的链式表示法
邻接表不唯一:因为各个边的链入顺序是任意的
邻接表和邻接矩阵的相异
邻接表算法实现
邻接表算法实现2
图的遍历:
从连通图的任意顶点出发,沿着一些边访遍图中所有顶点,且每个顶点仅被访问一次
实质:找每个顶点的邻接点
图的遍历通常有两种:深度优先和广度优先搜索
深度优先搜索(DFS)堆 基本思想:仿树的先序遍历
DFS算法实现
邻接表的DFS算法实现
DFS算法效率分析:
如果用邻接矩阵表示图:遍历图中每个顶点都要从头扫描该顶点所在行,时间复杂度为O(n2)
如果用邻接表表示图:虽然有2e个表结点,但只需扫描e个结点就可完成遍历,加上遍历头结点的时间,时间复杂度为O(n+e)
稠密图适用于邻接矩阵上进行深度遍历,稀疏图适用于邻接表上进行深度遍历
广度优先搜索(BFS)队列 :仿树的层次遍历,从上到下,从左到右
BFS例
BFS步骤
BFS算法实现
BFS算法效率分析:
如果用邻接表来表示图,则时间复杂度为d0+d1+...+dn-1=O(e),其中di表示顶点i的度
如果用邻接矩阵表视图,对于每个被访问到的顶点,都要循环检测矩阵中的一整行,所以时间复杂度为O(n2)
DFS和BFS的比较:
空间复杂度相同都是O(n),时间复杂度只与存储结构有关,与搜索路径无关
最短路径:
从图中某个顶点(源点)到另一个顶点(终点)之间的路径可能不止一条,找到一条沿此路径上权值和最小的路径
最短路径分为:单源点最短路径和所有顶点之间的最短路径
单源点最短路径:在图中给定源点,求从源点开始到所有各顶点之间的最短路径
Dijkstra(迪杰斯特拉算法):提出了一个路径长度递增次序,逐步从源点到其余各点的最短路径算法
迪杰斯特拉算法:
用一个邻接矩阵表示有向图中的顶点之间关系
一个集合存储顶点集合,开始只有源点;把后面求得的最短路径顶点放入集合中,知道所有顶点均放入集合中算法结束。
一个一维数组保存最短路径的长度
数组的作用
弗洛伊德算法思想
弗洛伊德算法
最小生成树:
生成树:一个极小连通子图,包含图中全部顶点但是只有n-1条边
生成森林:若干生成树组成,含全部顶点,但是构成这些树的边最少
对连通图进行遍历,得到的是一个极小连通子图,及图的生成树
深度优先搜索得到的是深度优先搜索生成树,广度优先搜索得到的是广度优先搜索树
非连通图进行遍历得到的是图的生成森林
图转生成树示例
图转生成森林
邻接表求生成森林
具体步骤
不同遍历方法得到不同生成树,不同顶点开始遍历得到不同生成树。按照生成树的定义:n个顶点的连通网络的生成树有n个顶点n-1条边
构造最小生成树准则:
必须只使用该网络中的边来构造最小生成树;必须使用且仅使用n-1条边来连接n个顶点;不能使用产生回路的边
求最小生成树:Kruskal(克鲁斯卡尔)算法和Prim(普里姆)算法;均是利用最小生成树MST性质构造
Kruskl算法:将边归并,适于求稀舒网的最小生成树
Prim算法:将顶点归并,与边无关,适于求稠密网的最小生成树
MST性质:若U集是V集的一个非空子集,若(u0,v0)是一条最小权值的边,且u0属于U,v0属于V-U,则(u0,v0)必在最小生成树上。
克鲁斯卡尔算法步骤
克鲁斯卡尔算法实例
计算机中实现克鲁斯卡尔算法
普利姆算法步骤
普利姆算法实例
计算机中实现普利姆算法
具体实例
网友评论