无向图,连通图

https://blog.csdn.net/kongduxue/article/details/81432270 https://blog.csdn.net/qq_33913037/article/details/71213985
**一、 图(Graph)**是由顶点(vertex)的有穷非空集合和顶点之间边(edge)的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合
a.若顶点之间 Vi 和 Vj 之间没有方向,则为无向边,用无序偶对( Vi , Vj )表示
b.若顶点之间 Vi 和 Vj 之间有方向,则为有向边(也称弧),用有序偶对< Vi , Vj >表示, Vi 为弧尾,Vj为弧头。
无向图:任意两顶点之间的边都是无向边,则该图为无向图。
有向图:任意两顶点之间的边都是有向边,则该图为有向图。
二、无向图的遍历
(1)深度优先遍历
基本思路:
a.访问顶点V
b.从V的未被访问的邻接点中选取一个顶点W,从W出发进行深度优先遍历
c.重复以上2步,直到图中所有和V有路径相通的顶点被访问到
在这里插入图片描述
伪代码:(类似树的前序遍历)
1.访问顶点,visited[v]=1;
2.w=顶点v的第一个邻接点;
3.while(w){
if(w未被访问) 从顶点w出发递归执行该算法
w=顶点v的下一个邻接点
}
(2)广度优先遍历
基本思路:
1.访问顶点V
2.依次访问V的各个未被访问的邻接点V1,V2,V3……VK
3.分别V1,V2,V3……VK从出发依次访问他们未被访问的邻接点,并使“先被访问顶点的邻接点”先于“后被访问顶点的邻接点”被访问,直到图中所有与顶点V有路径相通的顶点都被访问到
在这里插入图片描述
伪代码:(类似树的层序遍历)
1.初始化队列Q
2.访问顶点v,visited[v]=1,顶点入队Q;
3.while(队列Q非空){
v=队列Q的队头元素出队
w=顶点v的第一个邻接点
while(w存在){
if(w未访问){
访问顶点w,visited[w]=1;顶点w入队列Q
}
w=顶点v的下一个邻接点
}
}
三、连通图和连通分量
1.顶点间的连通性
在无向图G中,若从顶点vi到顶点vj有路径(当然从vj到vi也一定有路径),则称vi和vj是连通的。
2.连通图
 若V(G)中任意两个不同的顶点vi和vj都连通(即有路径),则称G为连通图(Con-nected Graph)。
  图G2,和G3是连通图。
  在这里插入图片描述
3.连通分量
 无向图G的极大连通子图称为G的最强连通分量(Connected Component)。
注意:
  ① 任何连通图的连通分量只有一个,即是其自身
 ② 非连通的无向图有多个连通分量。
【例】下图中的G4是非连通图,它有两个连通分量H1和H2。
在这里插入图片描述
强连通图和强连通分量

1.强连通图
  有向图G中,若对于V(G)中任意两个不同的顶点vi和vj,都存在从vi到vj以及从vj到vi的路径,则称G是强连通图。

2.强连通分量
 有向图的极大强连通子图称为G的强连通分量。
注意:
 ① 强连通图只有一个强连通分量,即是其自身。
 ② 非强连通的有向图有多个强连分量。
下图中的G1不是强连通图,因为v3到v2没有路径,但它有两个强连通分量,如右图所示。
在这里插入图片描述
网络(Network)

若将图的每条边都赋上一个权,则称这种带权图为网络(Network)。
注意:
  权是表示两个顶点之间的距离、耗费等具有某种意义的数。
在这里插入图片描述

  • 7
    点赞
  • 0
    评论
  • 18
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

delphi 为了完全支持OLE,32位Delphi 增加了Variant 数据类型,本节将从宏观角度来分析这种数据类型。实际上,Variant类型对Pascal语言有普遍而深入的影响,Delphi 控件库中与OLE 无关的地方也使用到这种类型。 Variant变量没有类型 一般说来,你可以用Variant 变量存储任何数据类型,对它执行各种操作和类型转换。需要注意的是:这违反了Pascal 语言的一贯原则,有悖于良好的编程习惯。variant 变量的类型检查和计算在运行期间才进行,编译器不会提示代码中的潜在错误,这些错误在进一步测试中才能发现。总之,你可以认为包含variant变量的代码是解释性代码,正如解释性代码一样,许多操作直到执行时才能知道,这对代码运行速度会有很大的影响。 上面对Variant 类型的使用提出了警告,现在来看看Variant 类型究竟能干什么。基本上说,如果声明了一个variant 变量: var V: Variant; 你就可以把各种不同类型的值赋给它: V := 10; V := 'Hello, World'; V := 45.55; 一旦得到一个variant 值,你可以把它拷贝给任何兼容或不兼容的数据类型。如果你把值赋给不兼容的数据类型,Delphi 会力尽所能进行转换,无法转换则颁布一个运行时间错误。实际上,variant变量中不仅包含了数据还包含有类型信息,并允许一系列运行时间操作,这些操作很方便,但运行速度慢且安全性差。 见例VariTest,它是上面代码的扩展。窗体上有三个编辑框,一对按钮,第一个按钮的OnClick 事件代码如下: procedure TForm1.Button1Click(Sender: TObject); var V: Variant; begin V := 10; Edit1.Text := V; V := 'Hello, World'; Edit2.Text := V; V := 45.55; Edit3.Text := V; end; 很有趣是不是?你可以把一个值为字符串的variant 变量赋给编辑框Text 属性,还可以把值为整数或浮点数的variant 变量赋给Text属性。正如你在10.1中所看到的,一切正常。 (10.1)按Assign按钮后,例VariTest的输出结果 10.1: 例 VariTest 的 Assign 按钮 Click 事件输出结果 更糟糕的是:你还可以用variant变量计算数值,从第二个按钮的Click事件代码就可看到这一点: procedure TForm1.Button2Click(Sender: TObject); var V: Variant; N: Integer; begin V := Edit1.Text; N := Integer(V) * 2; V := N; Edit1.Text := V; end; 至少这种代码带有一定危险性,如果第一个编辑框包含了一个数字,那么一切运行正常;如果不是,将会引发异常。这里再重申一遍,如果不到万不得以,不要随便使用Variant 类型,还是应坚持使用传统的Pascal 数据类型和类型检查方法。在Delphi 和 VCL中,variant变量主要是用于 OLE 支持和数据库域的访问。 Variant类型内部结构 Delphi中定义了一个 variant 记录类型,TVarData,它与Variant 类型有相同的内存布局。你可以通过TVarData访问variant变量的实际类型。TVarData 结构中包含了Variant类型信息(由Vtype域表示)、一些保留域及当前值。 VType域的取值包括OLE 自动化中的所有数据类型,这些类型通常叫OLE 类型或variant 类型。以下是variant 类型的完整列表,按字母顺序排列: varArray varBoolean varByRef varCurrency varDate varDispatch varDouble varEmpty varError varInteger varNull varOleStr varSingle varSmallint varString varTypeMask varUnknown varVariant 你可以在Delphi 帮助系统的variants 主题下找到这些类型的说明。 还有许多操作variant 变量的函数,你可以用它们进行特定的类型转换,或通过它们获取variant变量的类型信息(例如VarType 函数),当你用variant变量写表达式时,Delphi会自动调用这些类型转换和赋值函数。另外还有操作variant 数组的例程,你可以通过帮助文件的Variant support routines 主题了解相关内容。 Variant类型运行很慢! Variant 类型代码运行很慢,不仅数据类型转换如此,两个值为整数的Variant 变量相加也是如此。它们几乎跟Visual Basic这种解释性代码一样慢!为了比较Variant变量和整型变量的运行速度,请看例VSpeed 。 程序中设置了一个循环,记录运行时间并在进程条中显示运行状态。下面是基于variant类型的一段代码,基于整型的代码与此相似: procedure TForm1.Button1Click(Sender: TObject); var time1, time2: TDateTime; n1, n2: Variant; begin time1 := Now; n1 := 0; n2 := 0; ProgressBar1.Position := 0; while n1 < 5000000 do begin n2 := n2 + n1; Inc (n1); if (n1 mod 50000) = 0 then begin ProgressBar1.Position := n1 div 50000; Application.ProcessMessages; end; end; // we must use the result Total := n2; time2 := Now; Label1.Caption := FormatDateTime ( 'n:ss', Time2-Time1) + ' seconds'; end; 记时这段代码值得一看,因为你可以把它用到任何类型的性能测试中。正如你所看到的,程序用Now 函数获取当前的时间,用FormatDateTime 函数格式化时间差,输出结果以分("n")和秒("ss")表示。除此之外,你可以用Windows API的GetTickCount 函数,该函数能精确显示操作系统启动后至当前的毫秒数。 从上例可见两者的速度差异常之大,以至于不用精确记时也能看到这种差异。10.2是在本人计算机上运行程序看到的结果。当然运行结果取决于运行程序的计算机,但是两者的数值比不会有太大变化。
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值