学习 严蔚敏讲数据结构笔记16
来源:互联网 发布:做淘宝仓库打包员累吗 编辑:程序博客网 时间:2024/05/19 14:17
7.6 两点之间的最短路径问题
从原点到其余各点的最短路径。
算法的基本思想是:依路径长度递增的次序求得各条路径
假设图中所示为从原点到其余各点之间的最短路径,则在这些路径中,必然存在一条长度最短者。
在这条路径上,必定只含有一条(权值最小)弧,由此,只要在所有从原点出发的弧中查找权值最小者;
长度次短的路径可能有两种情况:它可能是从原点直接到改点的路径;也可能是,从原点a再到该点
其余依次类推。
假设Disk[k]表示当前所求得的从原点到顶点k的最短路径。则一般情况下,Disk[k]=<源点到顶点k的弧上的权值>或者=<源点到其它顶点路径的长度>+<其它顶点到顶点k弧上的权值>
每一对顶点之间的最短路径
算法的基本思想:从vi到vj的所有存在的路径中,选出一条最短的路径
若<vi,vj>存在,则存在路径{vi,vj}路径中不含其它顶点
若<vi,vl><vl,vj>存在,则存在路径{vi,vl,vj}路径中所含顶点序号不大于1
若{vi,…,v2},{v2,…,vj}存在,则存在一条路径{vi,…,v2,…vj}路径中所含顶点序号不大于2
依次类推,则vi到vj的最短路径应是上述着这些路径中,路径长度最小者
7.7拓扑排序
问题:假设以有向图表示一个工程的施工图或程序的数据流图,则图中不允许出现回路。
如何检查有向图是否存在回路的方法之一,是对有向图进行拓扑排序。
何谓“拓扑排序”?
对有向图进行如下操作:
按照有向图给出的次序关系,就爱那个图中顶点排成一个线性序列,对于有向图中没有限定次序关系的顶点,则可以人为加上任意的次序关系。
由此所得顶点的线性序列称之为拓扑有序序列
例如:对于下列有向图
可求得拓扑有序序列:ABCD或ACBD
反之,对于下列有向图
不能求得它的拓扑有序序列。因为图中存在一个回路{B,C,D}
如何进行拓扑排序?
一、从有向图中选取一个没有前驱的顶点,并输出之
二、从有向图中删去此顶点以及所有以它为尾的弧
重复上述两步,直至图空,或者图不空但找不到前驱的顶点为止。
没有前驱的顶点===入度为零的顶点
删除顶点及以它为尾的弧===弧头顶点的入度减1
算法取入度为零的顶点v
29_001
while(v <> 0)
{
printf(v);
++ m;
w: = FirstAdj(v);
while(w <> 0)
{
inDegree[w] --;
w: = newAdj(v, w);
}
//取下一个入度为零的顶点v;
}
if(m < n)
{
printf("图中有回路");
}
为避免每次都要搜索入度为零的顶点,在算法中设置一个“栈”,以保存“入度为零”的顶点。
29_002
CountInDegree(G, indegree); //对各顶点求入度
InitStack(S);
for(i = 0; i < G.vexnum; ++ i)
{
if(! indegree[i])
{
Push(S, i); //入度为零的顶点入栈
}
}
count = 0; //对输出顶点计数
while(! EmptyStack(S))
{
Pop(S, v);
++ count;
printf(v);
for(w = FirstAdj(v); w; w = NextAdj(G, v, w))
{
-- indegree(w);
}
if(! indegree[w])
{
Push(S, w); //新产生的入度为零的顶点入栈
}
}
if(count < G.vexnum)
{
printf("图中有回路");
}
7.8关键路径
假设以有向网表示一个施工流图,弧上的权值表示完成该项子工程所需时间
问:哪些子工程项是“关键工程?”?
即:将影响整个工程完成前的子工程项。
整个工程完成的时间为:从有向图的源点到汇点的最长路径
“关键活动”指的是:该弧上的权值增加静使有向图上的最长路径的长度增加。
如何求关键活动
“事件(顶点)”的最早发生时间ve(j),ve(j)=从原点到顶点j的最长路径长度;
“事件(顶点)”的最迟发生时间vl(k), vl(k)=从顶点k到汇点的最短路径长度;
假设第i条弧为<j,k>则第i项活动“活动(弧)”的最早开始时间ee(i),ee(i)=ve(j);
“活动(弧)”的最迟开始时间el(i),el(i)=vl(k)-dut(<j,k>);
事件发生时间的计算公式
Ve(原点)=0;
Ve(k)=Max{ve(j)+dut(<j,k>)}
Vl(汇点)=ve(汇点);
Vl(j)=Min{vl(k)-dut(<j,k>)}
算法的实现要点:
显然,求ve的顺序应该是按拓扑有序的次序;而求vl的顺序应该是按拓扑逆序的次序。因为,脱兔逆序序列即为拓扑有序序列的逆序列,因此,应该在拓扑排序的过程中,另设一个“栈”记下拓扑有序序列。
1. 熟悉图的各种存储结构及其构造算法,了解实际问题的求解效率与采用何种存储结构和算法有密切联系。
2. 熟练掌握图的两种搜索路径的遍历;遍历的逻辑定义,深度优先搜索的来年各种形式(递归和非i递归)和广度优先搜索的算法,在学习中应注意图的遍历算法域树的遍历算法之间的类似和差异。
3. 应用图的遍历算法求解各种简单路径问题
4. 理解教科书中讨论的各种图的算法。
5.4 广义表的类型定义
ADT Glist{
数据对象:D={ei|I= 1,2,…,n; n>=0; e∈AtomSet或ei∈GList,AtomSet为某个数据对象}
数据关系:LR={<ei-1,ei>|ei-1,ei∈D,2<=i<=n}
}
广义表是递归定义的线性结构。
一般情况下,广义表写成LS=(a1,a2,…,an)其中:ai或为原子或为广义表
广义表是一个多层次的线性结构
例如:D=(E,F) E=(a,(b,c)) F=(d,(e))
其它如:
A=()
B=(a,B)=(a,(a,(a,…,)))
C=(A,D,F)
广义表LS=(a1,a2,…an)的结构特点:
1) 广义表中的数据元素有相对次序
2) 广义表的长度定义为最外层包含元素个数
3) 广义表的深度定义为所含括弧的重数;
注意“原子”的深度为“0”。“空表”的深度为1
4) 广义表可以共享
5) 广义表可以是一个递归的表;递归表的深度是无穷值,长度是有限值。
6) 任何一个非空广义表LS(a1,a2,…,an)均可分解为表头Head(L,S)=a1和表尾Tail(LS)=(a2,…,an)两部分
例如:LS=(A,D)=((),(E,F))=((),((a,(b,c)),F)
Head(LS)=A Tail(LS)=(D)
Head(D)=E Tail(D)=(F)
Head(E)=a Tail(E)=((b,c))
Head(((b,c)))=(b,c) Tail(((b,c))=()
Head((b,c))=b Tail(b,c))=(c)
Head((c))=c Tail((c))=()
基本操作:
结构的创建和销毁
InitGList(&L);
DestroGList(&L);
CreateGList(&L, S);
CopyGList(&T, L)
状态函数
GListLength(L);
GListDepth(L);
GListEmpty(L);
GetHead(L);
GetTail(L);
插入和删除操作
InsertFirst(&L, e);
DeleteFirst(&L, &e);
遍历
Traverse_GL(L, Visit());
- 学习 严蔚敏讲数据结构笔记16
- 《数据结构》学习笔记 16
- 学习 严蔚敏讲数据结构笔记01
- 学习 严蔚敏讲数据结构笔记02
- 学习 严蔚敏讲数据结构笔记03
- 学习 严蔚敏讲数据结构笔记04
- 学习 严蔚敏讲数据结构笔记05
- 学习 严蔚敏讲数据结构笔记06
- 学习 严蔚敏讲数据结构笔记07
- 学习 严蔚敏讲数据结构笔记08
- 学习 严蔚敏讲数据结构笔记09
- 学习 严蔚敏讲数据结构笔记10
- 学习 严蔚敏讲数据结构笔记11
- 学习 严蔚敏讲数据结构笔记12
- 学习 严蔚敏讲数据结构笔记13
- 学习 严蔚敏讲数据结构笔记14
- 学习 严蔚敏讲数据结构笔记15
- 学习 严蔚敏讲数据结构笔记17
- 学习 严蔚敏讲数据结构笔记11
- 学习 严蔚敏讲数据结构笔记12
- 学习 严蔚敏讲数据结构笔记13
- 学习 严蔚敏讲数据结构笔记14
- 学习 严蔚敏讲数据结构笔记15
- 学习 严蔚敏讲数据结构笔记16
- 学习 严蔚敏讲数据结构笔记17
- 学习 严蔚敏讲数据结构笔记18
- 学习 严蔚敏讲数据结构笔记19
- 学习 严蔚敏讲数据结构笔记20
- 黑马训练营——java内存分配
- loadrunner常见问题汇总
- .net中获取周一、月初、月末、年初、年末
- C#索引器