用邻接多重表实现图遍历演示

合集下载

2022年东北石油大学计算机科学与技术专业《数据结构与算法》科目期末试卷A(有答案)

2022年东北石油大学计算机科学与技术专业《数据结构与算法》科目期末试卷A(有答案)

2022年东北石油大学计算机科学与技术专业《数据结构与算法》科目期末试卷A(有答案)一、选择题1、用数组r存储静态链表,结点的next域指向后继,工作指针j指向链中结点,使j沿链移动的操作为()。

A.j=r[j].nextB.j=j+lC.j=j->nextD.j=r[j]->next2、哈希文件使用哈希函数将记录的关键字值计算转化为记录的存放地址,因为哈希函数是一对一的关系,则选择好的()方法是哈希文件的关键。

A.哈希函数B.除余法中的质数C.冲突处理D.哈希函数和冲突处理3、若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用()存储方式最节省时间。

A.顺序表B.双链表C.带头结点的双循环链表D.单循环链表4、循环队列A[0..m-1]存放其元素值,用front和rear分别表示队头和队尾,则当前队列中的元素数是()。

A.(rear-front+m)%mB.rear-front+1C.rear-front-1D.rear-front5、向一个栈顶指针为h的带头结点的链栈中插入指针s所指的结点时,应执行()。

A.h->next=sB.s->next=hC.s->next=h;h->next=sD.s->next=h-next;h->next=s6、循环队列放在一维数组A中,end1指向队头元素,end2指向队尾元素的后一个位置。

假设队列两端均可进行入队和出队操作,队列中最多能容纳M-1个元素。

初始时为空,下列判断队空和队满的条件中,正确的是()。

A.队空:end1==end2;队满:end1==(end2+1)mod MB.队空:end1==end2;队满:end2==(end1+1)mod (M-1)C.队空:end2==(end1+1)mod M;队满:end1==(end2+1) mod MD.队空:end1==(end2+1)mod M;队满:end2==(end1+1) mod (M-1)7、若元素a,b,c,d,e,f依次进栈,允许进栈、退栈操作交替进行,但不允许连续三次进行退栈操作,则不可能得到的出栈序列是()。

采用邻接表存储结构实现图的广度优先遍历。

采用邻接表存储结构实现图的广度优先遍历。

精心整理课程设计题目九:图的广度优先遍历基本要求:采用邻接表存储结构实现图的广度优先遍历。

(2)对任意给定的图(顶点数和边数自定),建立它的邻接表并输出;(3)实现图的广度优先遍历*/#include<iostream.h>#include<stdio.h>#include<malloc.h>#defineMAX_NUM20intvisited[MAX_NUM]={0};typedefintVertexType;typedefenum{DG=1,UDG}GraphKind;typedefstructArcNode{intadjvex;intweight;structArcNode*nextarc;ArcNode*info;}ArcNode;typedefstructVNode{VertexTypedata;ArcNode*firstarc;}VNode,AdjList[MAX_NUM];typedefstruct{AdjListvertices;intvexnum,arcnum;GraphKindkind;}ALGraph;voidPRIN(ALGraph&G);voidCreat_adjgraph(ALGraph&G);voidbfs(ALGraph&G,intv);voidCreat_adjgraphDG(ALGraph&G);voidCreat_adjgraphUDG(ALGraph&G);voidCreat_adjgraph(ALGraph&G);voidCreat_adjgraphDG(ALGraph&G){inti,s,d;ArcNode*p=NULL,*q=NULL;G.kind=DG;printf("请输入顶点数和边数:");scanf("%d%d",&G.vexnum,&G.arcnum);for(i=0;i<G.vexnum;++i){printf("第%d个顶点信息:",i+1);scanf("%d",&G.vertices[i].data);G.vertices[i].firstarc=NULL;}for(i=0;i<G.arcnum;++i){printf("第%d条边的起始顶点编号和终止顶点编号:",i+1);scanf("%d%d",&s,&d);while(s<1||s>G.vexnum||d<1||d>G.vexnum){printf("编号超出范围,重新输入");scanf("%d%d",&s,&d);}s--;d--;p=new(ArcNode);p->adjvex=d;p->nextarc=G.vertices[s].firstarc;G.vertices[s].firstarc=p;}}voidCreat_adjgraphUDG(ALGraph&G){inti,s,d;ArcNode*p,*q;G.kind=UDG;printf("请输入顶点数和边数:");scanf("%d%d",&G.vexnum,&G.arcnum);for(i=0;i<G.vexnum;++i){printf("第%d个顶点信息:",i+1);scanf("%d",&G.vertices[i].data);G.vertices[i].firstarc=NULL;}for(i=0;i<G.arcnum;++i){printf("第%d条边的起始顶点编号和终止顶点编号:",i+1);scanf("%d%d",&s,&d);while(s<1||s>G.vexnum||d<1||d>G.vexnum){printf("编号超出范围,重新输入");scanf("%d%d",&s,&d);}s--;d--;p=new(ArcNode);p->adjvex=d;p->nextarc=G.vertices[s].firstarc;G.vertices[s].firstarc=p;q=new(ArcNode);q->adjvex=s;q->nextarc=G.vertices[d].firstarc;G.vertices[d].firstarc=q;}}voidPRIN(ALGraph&G){inti;ArcNode*p;if(G.kind==DG||G.kind==UDG){for(i=0;i<G.vexnum;++i){printf("V%d:",G.vertices[i].data);p=G.vertices[i].firstarc;while(p!=NULL){printf("%d\t",p->adjvex+1);p=p->nextarc;}printf("\n");}}}voidbfs(ALGraph&G,intv){v--;ArcNode*p;intqueue[MAX_NUM],front=0,rear=0;intw,i;for(i=0;i<G.vexnum;i++)visited[i]=0;printf("%4d",v+1);visited[v]=1;rear=(rear+1)%MAX_NUM;queue[rear]=v;while(front!=rear){front=(front+1)%MAX_NUM;w=queue[front];p=G.vertices[w].firstarc;while(p!=NULL){if(visited[p->adjvex]==0){printf("%3d",p->adjvex+1);visited[p->adjvex]=1;rear=(rear+1)%MAX_NUM;queue[rear]=p->adjvex;}p=p->nextarc;}}printf("\n");}voidCreat_adjgraph(ALGraph&G){printf("1:有向图2:无向图\n");printf("请根据上述提示输入图的类型:");scanf("%d",&G.kind);switch(G.kind){caseDG:Creat_adjgraphDG(G);PRIN(G);break;caseUDG:Creat_adjgraphUDG(G);PRIN(G);break;default:printf("ERROR");break;}}voidmain(){ALGraphG;Creat_adjgraph(G);printf("\n");printf("广度优先搜索遍历序列为:\n");bfs(G,1);printf("\n");}。

数据结构考试题目及答案

数据结构考试题目及答案

数据结构考试题⽬及答案数据结构试题6⼀、单项选择题(每⼩题3分,共30分)1.设栈的输⼊序列是1、2、3、4,则______不可能是其出栈序列。

( )[A] 1234 [B] 2134 [C] 1432 [D] 43122.在⼀个具有n个结点的线性链表中查找某个结点,若查找成功,需要平均⽐较_____个结点。

( )[A] n [B] n/2 [C] (n+1)/2 [D] (n-1)/23.设每个字符占⼀个字节,⼆维数组A中每个元素有6个字符组成,其⾏下标从0到9,列下标从0到3,元素_____当A按⾏优先存储起始地址与当A按列优先存储的起始地址相同。

( )[A] A[3][0] [B] A[3][1] [C] A[3][2] [D] A[2][3]4.具有2000个结点的⾮空⼆叉树的最⼩深度为_______。

( )[A] 9 [B] 10 [C] 11 [D] 125.已知某⼆叉树的后根序列是dabec,中根序列是debac,则先根序列是_____。

( )[A] acbed [B] decab [C] deabc [D] cedba6. ⽆向图中所有边的数⽬等于所有顶点的度数之和的_____倍。

( )[A] 1 [B] 2 [C] 1/2 [D] 不⼀定7.递归函数F(n)=F(n-1)+n+1(n>1)的递归体是_______。

( )[A] F(0)=0 [B] F(1)=1 [C] F(n)=n+1 [D] F(n)=F(n-1)+n+18. 若需要在O(nlog2n)的时间内完成对n个元素的排序,且要求排序是稳定的,则可选择的排序⽅法是_______。

( )[A] 快速排序[B] 堆排序[C] 归并排序[D] 直接插⼊排序9.在对n个元素的序列进⾏排序时,堆排序所需要的附加存储空间是__。

( )[A] O(1) [B] O(log2n) [C] O(n) [D] O(n log2n)10.假定有K个关键字互为同义词,若⽤线性探查法把这K个关键字存⼊散列表中,则总的探查次数⾄少为______。

图的遍历算法实验报告

图的遍历算法实验报告

图的遍历算法实验报告图的遍历算法实验报告一、引言图是一种常用的数据结构,用于描述事物之间的关系。

在计算机科学中,图的遍历是一种重要的算法,用于查找和访问图中的所有节点。

本实验旨在探究图的遍历算法,并通过实验验证其正确性和效率。

二、实验目的1. 理解图的基本概念和遍历算法的原理;2. 实现图的遍历算法,并验证其正确性;3. 比较不同遍历算法的效率。

三、实验方法1. 实验环境:使用Python编程语言进行实验;2. 实验步骤:a. 构建图的数据结构,包括节点和边的定义;b. 实现深度优先搜索(DFS)算法;c. 实现广度优先搜索(BFS)算法;d. 验证算法的正确性,通过给定的图进行遍历;e. 比较DFS和BFS的效率,记录运行时间。

四、实验结果1. 图的构建:我们选择了一个简单的无向图作为实验对象,包含6个节点和7条边。

通过邻接矩阵表示图的关系。

```0 1 1 0 0 01 0 1 1 0 01 1 0 0 1 10 1 0 0 0 00 0 1 0 0 00 0 1 0 0 0```2. DFS遍历结果:从节点0开始,遍历结果为0-1-2-4-5-3。

3. BFS遍历结果:从节点0开始,遍历结果为0-1-2-3-4-5。

4. 算法效率比较:我们记录了DFS和BFS算法的运行时间。

经实验发现,在这个图的规模下,DFS算法的运行时间为0.001秒,BFS算法的运行时间为0.002秒。

可以看出,DFS算法相对于BFS算法具有更高的效率。

五、讨论与分析1. 图的遍历算法能够帮助我们了解图中的节点之间的关系,有助于分析和解决实际问题。

2. DFS算法和BFS算法都可以实现图的遍历,但其遍历顺序和效率有所不同。

DFS算法会优先访问深度较大的节点,而BFS算法会优先访问离起始节点最近的节点。

3. 在实验中,我们发现DFS算法相对于BFS算法具有更高的效率。

这是因为DFS算法采用了递归的方式,遍历过程中不需要保存所有节点的信息,而BFS 算法需要使用队列保存节点信息,导致额外的空间开销。

第7章-2-(7.3图的遍历)

第7章-2-(7.3图的遍历)

v2 v3
2 v2
v1 v4
v5
3 V3
v1 v6
v7
4 V4 v2 v8
5 v5 6 v6 7 v7 8 v8
v2 v8 v3 v7 v3 v6 v4 v5
v,1
v,2
v1 v,4
v5
v1
v2
v,8
v4
v,5
v2
v8
v,3
v,6
v7
0
1 v1
v2 v3
2 v2
v1 v4
v5
3 V3
v1 v6
v7
v,6
v7
v2
v,8
v3
v,7
v4
v,5
v2
v8
v3
v6
0
1 v1
v2 v3
2 v2
v1 v4
v5
3 V3
v1 v6
v7
4 V4 v2 v8
5 v5 6 v6 7 v7 8 v8
v2 v8 v3 v7 v3 v6 v4 v5
v,1
v,2
v,3
v1 v,4
v5
v1
v,6
v7
v2
v,8
v3
v,7
v4
v,5
v3
3 V3
v1 v6
v7
4 V4 v2 v8
5 v5
v2 v8
v1 v,4
v5
v2
v,8
6 v6 7 v7 8 v8
v3 v7 v3 v6 v4 v5
v4
v,5
v2
v8
0
v,1
1 v1
v2 v3
2 v2
v1 v4

图练习与答案

图练习与答案

1. 首先将如下图所示的无向图给出英存储结构的邻接链表表示,然后写出对其分别进行深度,广度优先遍历的结果。

答•深度优先遍历序列:125967384宽度优先遍历序列:123456789注:(1)邻接表不唯一,这里顶点的邻接点按升序排列(2) 在邻接表确泄后,深度优先和宽度优先遍历序列唯一 (3) 这里的遍历,均从顶点1开始 2. 给出图G :画岀G 的邻接表表示图:3. 在什么情况下,Prim 算法与Kruskual 算法生成不同的MST?答.在有相同权值边时生成不同的MST,在这种情况下,用Prim 或Kruska 1也会生成不 同的应用丿 画出G 的深度优先生成树和广度优先生成树。

(1).HST4・已知一个无向图如下图所示,要求分别用Prim和Kruskal算法生成最小树(假设以①为起点,试画出构适过程)。

答.Prim算法构造最小生成树的步骤如24题所示,为节省篇幅,这里仅用Kruskal算法, 构造最小生成树过程如下:(下图也可选(2, 4)代替(3, 4), (5, 6〉代替⑴5))5.G=(V,E)是一个带有权的连通图,则:(1). ifi回答什么是G的最小生成树:(2). G为下图所示,请找出G的所有最小生成树。

答.(1)最小生成树的左义见上而26题(2)最小生成树有两棵。

邙艮于篇幅,下而的生成树只给岀顶点集合和边集合,边以三元组(Vi,Vj,W)形式),其中 W代表权值。

V (G) ={1, 2, 3, 4, 5} E1(G) = {(4, 5, 2), (2, 5, 4), (2, 3, 5), (1, 2,7) }:E2(G)={(4, 5, 2), (2, 4, 4), (2, 3, 5), (b 2、7) }6.请看下边的无向加权图。

(1).写出它的邻接矩阵。

(2).按Prim算法求其最小生成树, 并给出构造最小生成树过程中辅助数组的各分量值。

辅助数组各分量值:7.已知世界六大城市为:(Pe)、纽约(N)、巴黎(Pa).伦敦(L)、东京仃).墨西哥(M), 下表给泄了这六大城市之间的交通里程:世界六大城市交通里程表(单位:百公里)(1) .画岀这六大城市的交通网络图;(2) .画出该图的邻接表表示法;(3) .画岀该图按权值递增的顺序来构造的最小(代价)生成树.8.已知顶点1-6和输入边与权值的序列(如右图所示):每行三个数表示一条边的两个端点和貝权值,共11行。

使用有向图的邻接多重表

使用有向图的邻接多重表

使用有向图的邻接多重表
使用有向图的邻接多重表
有向图的邻接多重表是一种用于表示有向图的数据结构,它是一种结构化的方法,用于存储有向图中的顶点和边的信息。

它的基本思想是将有向图中的每个顶点和边都存储在一个多重表中,每个表都有一个头指针,指向该表中的第一个元素,每个元素都有一个指针,指向该表中的下一个元素,以此类推,形成一个链表。

有向图的邻接多重表有许多优点,首先,它可以有效地存储有向图中的顶点和边的信息,其次,它可以有效地查找有向图中的某个顶点的邻接顶点,这样可以更快地查找有向图中的某个顶点的邻接顶点,从而更快地完成有向图的遍历。

此外,有向图的邻接多重表还可以有效地添加和删除有向图中的顶点和边,从而更加方便地实现有向图的操作。

有向图的邻接多重表也有一些缺点,首先,它需要较多的存储空间,其次,它的查找效率较低,因为它需要遍历整个多重表来查找某个顶点的邻接顶点,这会耗费较多的时间。

总之,有向图的邻接多重表是一种有效的数据结构,它可以有效地存储有向图中的顶点和边的信息,可以有效地查找有向图中的某个顶点的邻接顶点,可以有效地添加和删除有向图中的顶点和边,但是它也有一些缺点,需要较多的存储空间,查找效率较低。

一种最短路径的演示算法

一种最短路径的演示算法




图 1 结点图
f. 4 nl 1




图 2 邻接 多重表 结构
2 顶点、 、XVTXNUM 0 ei n 2
tp d f t c { y e e r t su
f s Ed e i t g ; r
∥指 向第 一条 依 附于该 顶 点 的边 的 指针
∥顶 点类 型
} No e V d;
tp d f tu t y e e src {
VNod e;
∥顶 点 类 型
tp dfs u t y e e t c{ r
VN d j lt MA o eAdmui [ XVT s XNUM ] ;




, I 0l 1‘‘ j0 - 00 1 1 lO.0 I L1 1I L30 { 0 { f f \ I I1 I l L 2I 22 jI 0 ●’ lI 0 ’ I O l 2 4
关键 词 : 最短路 径 ; 杰 斯 特拉 算法 ; 接 多重表 迪 邻
中 图分 类 号 : 3 9 TP 1 文献 标 识 码 : A
1 基 本 目标
本 演 示算 法使 学 生对 最 短路 径 问题 有 了 一 个 深 刻 认 识 , 操 作 简 单 , 统 启 动 后 屏 幕 上 给 出提 示 信 它 系 息 , 生 可 以选 择 求最 短 路 径 或顶 点 信 息 . 学 为学 生 们 提供 了一 个 模 拟 环 境 , 可 将 其 应 用 到 导 游 咨询 系统 并 中 , 一个 比较 实用 的教 学 软 件 . 是 我们 假 定 最 短 路 径 模 型 中 , 点 数 为 n, 数 为 , 虑 到 道 路 网多 是 稀 结 边 考 疏 网 , 采用 邻 接多 重表 做 了存储 结 构 , 图 1为结 点 图 , 2为 其邻 接 多重 表 结构 . 故 下 图

图的定义和基本术语图的存储结构图的遍历生成树最短路径

图的定义和基本术语图的存储结构图的遍历生成树最短路径
操作结果: 在图G中增添新顶点v。
DeleteVex(&G, v) //删除顶点 初始条件: 图G存在, v和G中顶点有相同特性 。 操作结果:删除G中顶点v及其相关的弧。
InsertArc(&G, v, w) //插入弧 初始条件:图G存在,v 和w是G中两个顶点。 操作结果:在G中增添弧<v,w>,若G是无向的, 则还增添对称弧<w,v>。
DestroyGraph (&G ) // 销毁 初始条件:图G存在。 操作结果:销毁图G 。
LocateVex(G, u) // 定位 初始条件:图G存在,u 和G中顶点有相同特性 。 操作结果: 若G中存在顶点u ,则返回该顶点在 图中位置 ;否则返回其它信息。
GetVex(G, v)// 求值 初始条件:图G存在,v 是G中某个顶点。 操作结果:返回v的值。
//{有向图,有向网,无向图,无向网}
typedef struct ArcCell {// 弧的定义 VRType adj;//VRType是顶点关系类型。对无权图,
//用1或0表示相邻否;对带权图,则为权值类型。 InfoType *info; // 该弧相关信息的指针 } ArcCell ,
AdjMatrix[MAX_VERTEX_NUM] [MAX_VERTEX_NUM];
V2
V3
0110 0000 0001 10 0 0
//- -图的数组(邻接矩阵)存储表示--
#define INFINITY INT_MAX //最大值∞ #define MAX_VERTEX_NUM 20//最大顶点个数 typedef enum{DG,DN,UDG, UDN }graphkind;
表示,称为无向边;

图的遍历动态演示

图的遍历动态演示

图的遍历动态演示程序摘要:图是一种复杂的数据结构,具有较高的学习难度。

本文讲述了对图的动态演示程序的操作和程序的具体实现过程,使得我们对图的认识更深刻,学习更容易。

本软件以Visual Studio 2008作为开发工具,使用邻接表法,用MFC类库实现了对图的可视化创建和图的遍历的动态演示。

本文首先讲解了图的遍历动态演示程序的实现框架和设计思路,然后深入讲解了对图中结点和弧的创建、插入和删除,最后着重讲解了图的深度优先遍历和广度优先遍历动态演示的具体实现。

关键词:图; 遍历; 动态演示The dynamic demonstrative program of traverse graph Abstract:Graph is a complex data structure, which is hard to learn. This thesis tells people the manipulate of the dynamic demonstrate of traverse graph and the specific realization progress of the program. This study give us a deeper understanding of graph, as well as make it easier to learn it. This software realizes the visual creation of graph and the dynamic demonstration of traverse graph by using adjacent table, MFC library and Visual Studio 2008. This thesis firstly explains the realization of the dynamic demonstrate of traverse graph program, the go into the depth of the creation, insertion, deleting of node and arc, at last explains emphatically the actual realization of the Depth-First traverse of graph and the Breadth-First traverse of graph.Key Words:graph, traverse, dynamic demonstrative目录1 引言 (1)1.1 开发背景 (1)1.2 开发的目的以及意义 (1)2 需求分析 (1)2.1 功能概述 (1)2.2 功能需求分析 (2)2.2.1 结点的操作 (2)2.2.2 弧的操作 (2)2.2.3 自动生成图的支持 (2)2.2.4 支持图的销毁 (3)2.2.5 图的遍历类型 (3)2.2.6 图的存储结构 (3)2.2.7 图的遍历代码 (3)2.2.8 支持图的遍历次序显示和中间辅助队列的进出队情况显示 (3)2.2.9 支持对遍历速度的设置 (3)2.2.10 支持暂停和单步 (3)2.2.11 支持对图的实现代码的查看和运行 (4)2.2.12 支持对版本和帮助的显示 (4)3 总体设计 (4)3.1 程序框架的搭建 (4)3.1.1 工程项目的创建 (4)3.1.2 窗口的显示 (4)3.2 菜单的制作 (6)3.2.1 创建图 (6)3.2.2 设置演示速度 (8)3.2.3 查看源代码的实现 (8)3.2.4 运行此程序菜单的实现 (9)3.2.5 打开此文件菜单和帮助菜单的实现 (10)3.2.5 版本菜单的实现 (10)3.2.6 退出菜单功能的实现 (10)3.3图的创建和遍历核心算法的设计与实现 (10)3.3.1 算法的设计 (10)3.3.2 核心算法的实现 (16)4 测试与总结 (28)谢辞 (29)参考文献 (30)1 引言在纷繁复杂的社会生活中,很多东西都涉及到图的应用问题。

Java实现无向图的建立与遍历

Java实现无向图的建立与遍历

Java实现⽆向图的建⽴与遍历⼀、基于邻接矩阵表⽰法的⽆向图 邻接矩阵是⼀种利⽤⼀维数组记录点集信息、⼆维数组记录边集信息来表⽰图的表⽰法,因此我们可以将图抽象成⼀个类,点集信息和边集信息抽象成类的属性,就可以在Java中描述出来,代码如下:1class AMGraph{23private String[] vexs = null; //点集信息45private int[][] arcs = null; //边集信息67 } 每⼀个具体的图,就是该类的⼀个实例化对象,因此我们可以在构造函数中实现图的创建,代码如下:1public AMGraph(int vexNum,int arcNum) { //输⼊点的个数和边的个数23this.vexs = new String[vexNum];4this.arcs = new int[vexNum][vexNum];56 System.out.print("请依次输⼊顶点值,以空格隔开:");7 Scanner sc = new Scanner(System.in);8for(int i = 0; i < vexNum; i++) { //根据输⼊建⽴点集9this.vexs[i] = sc.next();10 }1112for(int i = 0; i < vexNum; i++) { //初始化边集13for(int j = 0; j < vexNum; j++) {14this.arcs[i][j] = 0; //0表⽰该位置所对应的两顶点之间没有边15 }16 }1718 start:for(int i = 0; i < arcNum; i++) { //开始建⽴边集1920 sc = new Scanner(System.in);21int vex1Site = 0;22int vex2Site = 0;23 String vex1 = null;24 String vex2 = null;2526 System.out.print("请输⼊第" + (i+1) + "条边所依附的两个顶点,以空格隔开:");27 vex1 = sc.next();28 vex2 = sc.next();29for(int j = 0; j < this.vexs.length; j++) { //查找输⼊的第⼀个顶点的位置30if (this.vexs[j].equals(vex1)) {31 vex1Site = j;32break;33 }34if (j == this.vexs.length - 1) {35 System.out.println("未找到第⼀个顶点,请重新输⼊!");36 i--;37continue start;38 }39 }40for (int j = 0; j < this.vexs.length; j++) { //查找输⼊的第⼆个顶点的位置41if(this.vexs[j].equals(vex2)) {42 vex2Site = j;43break;44 }45if (j == this.vexs.length - 1) {46 System.out.println("未找到第⼆个顶点,请重新输⼊!");47 i--;48continue start;49 }50 }51if(this.arcs[vex1Site][vex2Site] != 0) { //检测该边是否已经输⼊52 System.out.println("该边已存在!");53 i--;54continue start;55 }else {56this.arcs[vex1Site][vex2Site] = 1; //1表⽰该位置所对应的两顶点之间有边57this.arcs[vex2Site][vex1Site] = 1; //对称边也置158 }59 }60 System.out.println("基于邻接矩阵的⽆向图创建成功!");61 sc.close();62 } 创建好图后,我们还要实现图的遍历。

考研计算机专业基础综合(单项选择题)模拟试卷44(题后含答案及解析)

考研计算机专业基础综合(单项选择题)模拟试卷44(题后含答案及解析)

考研计算机专业基础综合(单项选择题)模拟试卷44(题后含答案及解析)题型有:1.1.下列页面置换算法中,可能会产生Belady异常现象的是( )。

A.先进先出算法FIFOB.最近最少使用算法LRUC.利用reference bit的近似的LRUD.最优算法optimall正确答案:A解析:Belady现象指为进程分配的内存页增加,缺页率反而增加的异常现象。

知识模块:操作系统2.对磁盘请求重新排队的目的是( )。

A.重置移臂时间B.让优先级高的进程先I/OC.减少传输时间D.减少旋转时间正确答案:D 涉及知识点:操作系统3.下面函数的功能是实现分块查找,空白处应该添加的内容是( )。

int BlkSearch(int*nz,mt key,int block,int BLK,int len) { int i;block=block-1;if(len<=0) { puts(”表为空!.”):return 0:} if(BLKd>len)BLK=len;for(i=block*BLK;i<(block+1)*BLK&&nz[i]!=0;i++) { if( ) { printf(”找到第%d个数是%d\n”,i,key);return 0:} }printf(”\n”);printf(”查找结束\n”);return 0;} A.nz[i]==keyB.nz[i]==BLKC.nz[i]==blockD.nz[i]==0正确答案:A解析:如果当前的值与所查找关键字相等,则完成查找。

知识模块:数据结构4.下面给出的4种排序方法中,( )排序法是不稳定性排序法。

A.插入B.冒泡C.二路归并D.堆正确答案:D解析:此题考查的知识点是排序算法的稳定性问题。

如果待排序的文件中,存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,则称这种排序是稳定的排序:反之,若具有相同关键字的记录之间的相对次序发生变化,则称这种排序是不稳定的排序。

建立无向图的邻接多重表

建立无向图的邻接多重表

建立无向图的邻接多重表数据结构C语言版#include <stdio.h>#include <malloc.h>#define MAX_NAME 3 // 顶点字符串的最大长度+1#define MAX_INFO 80 // 相关信息字符串的最大长度+1typedef char InfoType;typedef char VertexType[MAX_NAME]; // 字符串类型// AMLGraph.h 无向图的邻接多重表存储表示#define MAX_VERTEX_NUM 20typedef enum{unvisited,visited}VisitIf;typedef struct EBox{VisitIf mark; // 访问标记int ivex,jvex; // 该边依附的两个顶点的位置struct EBox *ilink,*jlink; // 分别指向依附这两个顶点的下一条边InfoType *info; // 该边信息指针}EBox;typedef struct{VertexType data;EBox *firstedge; // 指向第一条依附该顶点的边}VexBox;typedef struct{VexBox adjmulist[MAX_VERTEX_NUM];int vexnum,edgenum; // 无向图的当前顶点数和边数}AMLGraph;typedef int QElemType;// 单链队列--队列的链式存储结构typedef struct QNode{QElemType data; //数据域struct QNode *next; //指针域}QNode,*QueuePtr;typedef struct{QueuePtr front,//队头指针,指针域指向队头元素rear; //队尾指针,指向队尾元素}LinkQueue;// 若G中存在顶点u,则返回该顶点在无向图中位置;否则返回-1 int LocateVex(AMLGraph G,VertexType u){int i;for(i=0;i<G.vexnum;++i)if(strcmp(u,G.adjmulist[i].data)==0)return i;return -1;}// 采用邻接多重表存储结构,构造无向图Gint CreateGraph(AMLGraph *G){int i,j,k,l,IncInfo;char s[MAX_INFO];VertexType va,vb;EBox *p;printf("请输入无向图G的顶点数,边数,边是否含其它信息(是:1,否:0): ");scanf("%d,%d,%d",&(*G).vexnum,&(*G).edgenum,&IncInfo);printf("请输入%d个顶点的值(<%d个字符):\n",(*G).vexnum,MAX_NAME);for(i=0;i<(*G).vexnum;++i) // 构造顶点向量{scanf("%s",(*G).adjmulist[i].data);(*G).adjmulist[i].firstedge=NULL;}printf("请顺序输入每条边的两个端点(以空格作为间隔):\n");for(k=0;k<(*G).edgenum;++k) // 构造表结点链表{scanf("%s%s%*c",va,vb); // %*c吃掉回车符i=LocateVex(*G,va); // 一端j=LocateVex(*G,vb); // 另一端p=(EBox*)malloc(sizeof(EBox));p->mark=unvisited; // 设初值p->ivex=i;p->jvex=j;p->info=NULL;p->ilink=(*G).adjmulist[i].firstedge; // 插在表头(*G).adjmulist[i].firstedge=p;p->jlink=(*G).adjmulist[j].firstedge; // 插在表头(*G).adjmulist[j].firstedge=p;if(IncInfo) // 边有相关信息{printf("请输入该弧的相关信息(<%d个字符):",MAX_INFO);gets(s);l=strlen(s);if(l){p->info=(char*)malloc((l+1)*sizeof(char));strcpy(p->info,s);}}}return 1;}// 返回v的值VertexType* GetVex(AMLGraph G,int v){if(v>=G.vexnum||v<0)exit(0);return &G.adjmulist[v].data;}// 对v赋新值valueint PutVex(AMLGraph *G,VertexType v,VertexType value) {int i;i=LocateVex(*G,v);if(i<0) // v不是G的顶点return 0;strcpy((*G).adjmulist[i].data,value);return 1;}// 返回v的第一个邻接顶点的序号。

中南大学《数据结构》课程作业(在线作业)二及参考答案

中南大学《数据结构》课程作业(在线作业)二及参考答案

(一) 单选题1. 用邻接表表示图进行深度优先遍历时,通常是采用()来实现算法的。

(A) 栈(B) 队列(C) 树(D) 图参考答案: (A)2. 设图的邻接链表如图所示,则该图的边的数目是()。

(A) 4(B)5 (C) 10(D) 20参考答案: (B)3. 若采用邻接矩阵翻存储一个n 个顶点的无向图,则该邻接矩阵是一个()。

(A)上三角矩阵(B)稀疏矩阵(C)对角矩阵(D)对称矩阵参考答案: (D)4.无向图,其中:,对该图进行深度优先遍历,得到的顶点序列正确的是()。

(A)a,b,e,c,d,f (B)a,c,f,e,b,d (C)a,e,b,c,f,d(D)a,e,d,f,c,b参考答案: (D)5. 设森林F 对应的二叉树为B ,它有m 个结点,B 的根为p ,p 的右子树结点个数为n,森林F 中第一棵子树的结点个数是()。

(A)(B)(C)(D) 条件不足,无法确定参考答案: (A)6. 关键路径是事件结点网络中()。

(A) 从源点到汇点的最长路径(B) 从源点到汇点的最短路径(C) 最长回路(D) 最短回路参考答案: (A)7. 树最适合用来表示()。

(A)有序数据元素(B) 无序数据元素(C) 元素之间具有分支层次关系的数据(D) 元素之间无联系的数据参考答案:(C)8. 在一棵具有n个结点的二叉链表中,所有结点的空域个数等于()。

(A)n(B)(C)(D)参考答案:(C)9. 在一个非空二叉树的中序遍历序列中,根结点的右边()。

(A)只有右子树上的所有结点(B) 只有右子树上的部分结点(C) 只有左子树的上的部分结点(D) 只有左子树上的所有结点参考答案:(A)10. 有8个结点的无向连通图最少有()条边。

(A)5 (B) 6 (C) 7 (D) 8参考答案:(C)11. 含有10个结点的二叉树中,度为0的结点数为4,则度为2的结点数为()。

(A)3 (B) 4 (C) 5 (D) 6参考答案:(A)12. 在有n个叶子结点的哈夫曼树中,其结点总数为()。

数据结构课程设计(C语言版)飞机订票系统

数据结构课程设计(C语言版)飞机订票系统

———C语言版课题:飞机订票系统和图的遍历的动态演示姓名:学号:班级:指导教师:订票系统1.需求分析任务:通过此系统可以实现如下功能:录入:可以录入航班情况(数据可以存储在一个数据文件中,数据结构、具体数据自定)查询:可以查询某个航线的情况(如,输入航班号,查询起降时间,起飞抵达城市,航班票价,票价折扣,确定航班是否满仓);可以输入起飞抵达城市,查询飞机航班情况;订票:(订票情况可以存在一个数据文件中,结构自己设定)可以订票,如果该航班已经无票,可以提供相关可选择航班;退票:可退票,退票后修改相关数据文件;客户资料有姓名,证件号,订票数量及航班情况,订单要有编号。

修改航班信息:当航班信息改变可以修改航班数据文件要求:根据以上功能说明,设计航班信息,订票信息的存储结构,设计程序完成功能;2:主要设计思路:1)算法构造流程图:A:主菜单:B:各分块模板的构造流程图:3:功能函数设计:(1):订票系统主菜单函数 menu_select()本函数主要构造系统的主菜单,系统需要实现很多功能,并且各个功能需要各自的函数支持,所以通过主菜单可以轻松的进入各个函数下实现各自的功能,故主菜单显得尤为重要。

其实就是通过键盘输入选择项,然后通过scanf接受,在通过swtich判断进入各个选择项。

(2):工作人员管理函数 enter()&change()系统需要各个航班的详细信息,所以需要工作人员把信息输入系统里,以供乘客查询订票。

enter()函数的构造就是为了解决这个问题。

而有可能航班线路更改或由于天气等原因飞机的起飞时间发生了更改,故工作人员需要及时更改信息,所以需要构造change()函数。

(3):列出航班信息的函数 list()乘客需要查询各个航班的信息,所以通过系统要能调出上面工作人员已经录入好的航班信息,所以构造本函数来实现这个功能。

(4)乘客具体查询函数 search()本函数分两个分函数:search1()和search2(),它们分别实现乘客的按航班查询和按出发及抵达城市的两种查询方案。

数据结构与算法_常熟理工学院中国大学mooc课后章节答案期末考试题库2023年

数据结构与算法_常熟理工学院中国大学mooc课后章节答案期末考试题库2023年

数据结构与算法_常熟理工学院中国大学mooc课后章节答案期末考试题库2023年1.下列排序方法中,不稳定的排序方法有()。

参考答案:希尔排序2.下列排序方法中,稳定的排序方法有()。

参考答案:归并排序3.对n个不同的关键字由小到大进行冒泡排序,在下列()情况下比较的次数最少。

参考答案:从小到大排列好的4.散列表中哈希冲突指的是()。

参考答案:不同键值对应相同的哈希函数值5.分别以下列序列构造二叉排序树,与用其它三个序列所构造的结果不同的是()。

参考答案:(80,70, 85, 65, 75,90,95)6.若一个广义表的表头为空表,则此广义表亦为空表。

参考答案:错误7.已知关键字序列{418,34,89,110,505,333,96,693,176},使用直接插入法按递增排序,第三趟排序的的结果为——————————————————————。

参考答案:34,89,418,110,505,333,96,693,176##%_YZPRLFH_%##34,89,418,110,505,333,96,693,1768.写出下面算法的功能。

typedef struct{ int vexnum,arcnum; char vexs[N]; intarcs[N][N];}graph;void funtion(int i,graph *g){ int j; printf("node:%c\n",g->vexs[i]); visited[i]=TRUE; for(j=0;jvexnum;j++) if((g->arcs[i][j]==1)&&(!visited[j])) function(j,g); }参考答案:深度优先9.某二叉树的中序序列为DBEAC,后序序列为DEBCA,则其先序序列为。

参考答案:ABDEC10.不是算法的基本特性参考答案:在规定的时间内完成11.在下列存储形式中,()不是树的存储形式。

图-存储结构-邻接多重表

图-存储结构-邻接多重表

图-存储结构-邻接多重表⽂字描述 邻接多重表是⽆向图的另⼀种链式存储结构. 虽然邻接表是⽆向图的⼀种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每⼀条边(vi,vj)有两个结点,分别在第i个和第j个链表中,这给某些图的操作带来不便。

如对已被搜索过的边作记号或删除⼀条边等,此时需要找到表⽰同⼀条边的两个结点。

因此,在进⾏这类操作的⽆向图的问题中采⽤邻接多重表更合适。

邻接多重表的结构和⼗字链表类型。

边结点和顶点结点如下⽰: 边结点由6个域组成:mark为标志域,可标记这条边是否被搜索过; ivex和jvex为该边依附的两个顶点在图中的位置;ilink指向下⼀条依附于顶点ivex的边;jlink指向下⼀条依附于顶点jvex的边,info为指向和边相关的各种信息的指针域。

顶点结点由2个域组成:data存储和该顶点相关的信息如顶点名称;firstedge域指⽰第⼀条依附于该顶点的边。

⽰意图算法分析 建⽴邻接多重链表的时间复杂度和建⽴邻接表是相同的. 另外邻接多重表⼏乎只针对⽆向图或⽆向⽹。

代码实现1/*2以邻接多重表作为图的存储结构创建⽆向图。

3*/4 #include <stdio.h>5 #include <stdlib.h>6 #include <string.h>78#define MAX_VERTEX_NUM 209 typedef enum {DG, DN, UDG, UDN} GraphKind;10 typedef enum {unvisited, visited} VisitIf;11 typedef char InfoType;12 typedef char VertexType;13//顶点结点14 typedef struct EBox{15 VisitIf mark;//访问标记16int ivex, jvex;//该边依附的两个顶点的位置17struct EBox *ilink, *jlink;//分别指向依附这两个顶点的下⼀条边18 InfoType *info;//该边信息指针19 }EBox;20//边结点21 typedef struct VexBox{22 VertexType data;//存储顶点名称23 EBox *firstedge;//指向第⼀条依附该顶点的边24 }VexBox;25//图结点26 typedef struct{27 VexBox adjmulist[MAX_VERTEX_NUM];28int vexnum,edgenum; //⽆向图的当前顶点数和边数29 GraphKind kind;30 }AMLGraph;3132/*33若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。

c++实现有向图邻接表求入度,出度,删除、增加顶点,弧,深度遍历及其生成树等

c++实现有向图邻接表求入度,出度,删除、增加顶点,弧,深度遍历及其生成树等

c++实现有向图邻接表求入度,出度,删除、增加顶点,弧,深度遍历及其生成树等#include "stdio.h"#include "math.h"#include"malloc.h"#include "stack"#include#define OK 1#define ERROR -1#define MAX 32764 // 最大值∞//#define MaxLen 1000#define STACK_INIT_SIZE 100#define STACKINCREMENT 10#define MAX_VERTEX_NUM 50 // 最大顶点个数typedef enum {DG, DN, AG, AN} GraphKind; //{有向图,有向网,无向图,无向网}typedef int status;typedef int VRType;typedef int InfoType;typedef char VertexType;typedef char TElemType;typedef char QElemType;/*--------------------图的邻接矩阵存储表示---------------------*/typedef struct ArcCell {VRType adj; // VRType是顶点关系类型。

对无权图,用1或0表示相邻否;// 对带权图,则为权值类型。

InfoType *info; // 该弧相关信息的指针}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{VertexType vexs[MAX_VERTEX_NUM]; // 顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数和弧数GraphKind kind; // 图的种类标志}MGraph;/*------------------------图的邻接表存储表示-----------------*/ typedef struct ArcNode {int weight;int adjvex; // 该弧所指向的顶点的位置struct ArcNode *nextarc; // 指向下一条弧的指针InfoType *info; // 该弧相关信息的指针}ArcNode;typedef struct VNode {VertexType data; // 顶点信息ArcNode *firstarc; // 指向第一条依附该顶点的弧}VNode, AdjList[MAX_VERTEX_NUM];typedef struct {AdjList vertices;int vexnum, arcnum; // 图的当前顶点数和弧数GraphKind kind; // 图的种类标志}ALGraph;/*------------------------树的孩子兄弟存储表示-----------------*/typedef struct CSNode{TElemType data;struct CSNode *firstchild,*nextsibling;} CSNode, *CSTree;/*------------------------队列的存储结构-------------------------*/typedef struct QNode{QElemType data;struct QNode *next;} QNode, *QueuePtr;typedef struct {QueuePtr front;QueuePtr rear;} LinkQueue;/*----------------------单链队列的相关算法-------------------------*///构造空队列status InitQueue(LinkQueue &Q){Q.rear=Q.front=(QueuePtr)malloc(sizeof(QNode));if(!Q.front) return (OVERFLOW);Q.front->next=NULL;return OK;}//队是否为空bool QueueEmpty(LinkQueue Q){if(!Q.front->next)return (true);return (false);}//入队status EQueue(LinkQueue &Q, QElemType e){ QNode *p;p=(QNode *)malloc( sizeof(QNode));if (!p) return (OVERFLOW);p->data= e;p->next=NULL;Q.rear->next=p;Q.rear=p;return(OK);}//出队status DeQueue(LinkQueue &Q, QElemType &e){ QNode *p;if(!Q.front) return (OVERFLOW);p=Q.front->next;e=p->data;Q.front->next=p->next;if(Q.rear==p) Q.rear=Q.front;free(p);return (OK);}/*--------------------------栈的基本操作-------------------------------------------*///栈的存储结构typedef char SElemType;typedef struct {SElemType *base; //栈底指针SElemType *top; //栈顶指针int stacksize; //栈的大小}SqStack;//构造空栈status InitStack (SqStack &S){S.base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));if (!S.base) return(OVERFLOW);S.stacksize = STACK_INIT_SIZE;S.top = S.base;return(OK);}//出栈status Pop(SqStack &S, SElemType &e){if(S.base == S.top) return(ERROR);//栈空e=*--S.top;return(OK);}//入栈status Push(SqStack &s,SElemType e) {if(s.top-s.base>=s.stacksize)return OVERFLOW;*s.top++=e;return OK;}//销毁栈status DestroyStack(SqStack &S){S.top=NULL;S.base=NULL;delete[] S.base;S.stacksize=0;return OK;}//判断栈是否为空int EmptyStack(SqStack s){if(s.top==s.base) return 1;else return 0;}//得到栈顶元素status GetTop(SqStack &s,SElemType &e) {if(s.top==s.base) return ERROR;e=*(s.top-1);return OK;}//栈的长度int StackLength(SqStack s){return s.top-s.base;}//得到栈的所有元素值status Get(SqStack s){int i,n;n=StackLength(s);if(!n) return ERROR;for(i=0;i<n;i++)printf("%c\t",*(s.base+i));return OK;}/*-----------------------创建有向图的邻接矩阵-----------------*///元素在图中的位置int locateMG(MGraph g,VertexType v){for(int i=0;i<g.vexnum;i++){if(g.vexs[i]==v)return i;}return -1;}//边是否存在status arcExist(MGraph g,int i,int j){if(g.arcs[i][j].adj==MAX)return 0;return 1;}//图是否存在int ExistM(MGraph g){if(g.vexnum<0){printf("图不存在,请先创建图\n");return 0;}return 1;}//创建有向图的邻接矩阵status createMDG(MGraph &g){int i,j,k,n,l;VertexType v,v1,v2;printf("请输入有向图的顶点数:");scanf("%d",&g.vexnum);i=g.vexnum*(g.vexnum-1);printf("请输入有向图的弧数:");scanf("%d",&g.arcnum);while(g.arcnum>i){printf("\n输入有误,边数不能超过%d,请重新输入!",i);printf("\n请输入有向图的弧数:");scanf("%d",&g.arcnum);}for(i=0;ifor(j=0;j<g.vexnum;j++)g.arcs[i][j].adj=MAX;printf("请依次输入有向图的各个顶点(用回车分隔):");for(i=0;igetchar();scanf("%c",&v);l=locateMG(g,v);if(l>0){printf("输入的顶点重复,请重新输入\n");i--;continue;}g.vexs[i]=v;}for(k=1;k<=g.arcnum;k++){//构造邻接矩阵getchar();printf("请输入第%d条弧的起点与终点(用逗号分隔):",k); scanf("%c,%c",&v1,&v2);i=locateMG(g,v1);j=locateMG(g,v2);if(i<0||j<0||i==j||arcExist(g,i,j)){printf("输入错误,请重新输入\n");k--;continue;}prin</g.vexnum;j++)</g.vexnum;i++){</n;i++)tf("请输入第%d条弧的权值:",k);scanf("%d",&n);g.arcs[i][j].adj=n;}printf("有向图的邻接矩阵创建成功\n");return OK;}/*---------------------创建有向图的邻接表--------------------*///元素在图中的位置int locateALG(ALGraph g,VertexType v){for(int i=0;i<g.vexnum;i++){if(g.vertices[i].data==v)return i;}return -1;}//当前有向图中是否存在边int GraphExist(ALGraph G,int i,int j){ArcNode *s;s=G.vertices[i].firstarc;while(s&&s->adjvex!=j)s=s->nextarc;if(s) return 1;else return 0;}//图是否存在int ExistG(ALGraph g){if(g.vexnum<0){printf("图不存在,请先创建图\n");return 0;}return 1;}status CreateADG(ALGraph &g){int i,j,k,l,n;ArcNode *p;VertexType v1,v2;char c;printf("请输入有向图的顶点数:");scanf("%d",&g.vexnum);while(g.vexnum>MAX_VERTEX_NUM){printf("\n输入有误,顶点数不能超过%d,请重新输入!",MAX_VERTEX_NUM);printf("\n请输入有向图的顶点数:");scanf("%d",&g.vexnum);}i=g.vexnum*(g.vexnum-1);printf("请输入有向图的边数:");scanf("%d",&g.arcnum);while(g.arcnum>i){printf("\n输入有误,边数不能超过%d,请重新输入!",i);printf("\n请输入有向图的边数:");scanf("%d",&g.arcnum);}printf("请依次输入有向图的各个顶点(用回车分隔):");for(i=0;igetchar();scanf("%c",&c);l=locateALG(g,c);if(l>=0){printf("输入的顶点重复,请重新输入\n");i--;continue;}g.vertices[i].data=c;g.vertices[i].firstarc=NULL;}for(k=0;kgetchar();printf("请输入第%d条弧的起点与终点(用逗号分隔):",k+1); scanf("%c,%c",&v1,&v2);i=locateALG(g,v1);j=locateALG(g,v2);if(i<0||j<0||i==j||GraphExist(g,i,j)){printf("输入错误,请重新输入\n");k--;continue;}p=(ArcNode*)malloc(sizeof(ArcNode));//建立结点if(!p) return ERROR;printf("请输入第%d条弧的权值:",k+1);scanf("%d",&n);p->adjvex=j;p->nextarc=g.vertices[i].firstarc;//顶点i的链表g.vertices[i].firstarc=p;//添加到最左边p->weight=n;}printf("有向图的邻接表创建成功\n");return OK;}/*------------------------------输出图的信息-------------------*/void printGra(ALGraph G){ArcNode *p;int i;printf("图中有%d个顶点,%d条弧:\n",G.vexnum,G.arcnum);for(i=0;i<g.vexnum;i++){p=G.vertices[i].firstarc;printf("%c\t",G.vertices[i].data);while(p){printf("<%c,%c,%d>\t",G.vertices[i].data,G.vertices[p->adjve x].data,p->weight);p=p->nextarc;}printf("\n");}}void printMg(MGraph g){int i,j;for(i=0;i<g.vexnum;i++){printf("%c\t",g.vexs[i]);for(j=0;j<g.vexnum;j++){if (g.arcs[i][j].adj!=MAX)</g.vexnum;j++)</g.vexnum;i++){</g.vexnum;i++){</g.vexnum;i++){printf("<%c,%c,%d>\t",g.vexs[i],g.vexs[j],g.arcs[i][j].adj);}printf("\n");}}/*--------------------邻接表深度优先遍历并判断图的连通性-----------------*/ArcNode *nextnode=NULL;//全局变量bool visited[21];//全局变量//得到i号顶点的第一个邻接点int FirstAdjVex(ALGraph g,int i){ArcNode *p;p=g.vertices[i].firstarc;if(!p) return -1;nextnode=p->nextarc;return(p->adjvex);}//得到i号顶点的下一个邻接点int NextAdjVex(ALGraph g,int i){if(!nextnode) return -1;int m=nextnode->adjvex;nextnode=nextnode->nextarc;return m;}//访问图中的i号顶点void visitvex(ALGraph g,int i){printf("%c\t",g.vertices[i].data);}//从图某个顶点进行深度优先遍历int DFS(ALGraph g,int i){int w;visited[i]=true;visitvex(g,i);for(w=FirstAdjVex(g,i);w>=0;w=NextAdjVex(g,i))if(!visited[w]) DFS(g,w);return OK;}//对图进行深度优先遍历status DFSTraverse(ALGraph g){int v,u,x;int count[100];for(v=0;v<g.vexnum;v++){count[v]=0;printf("从%c开始深度优先遍历的结果:",g.vertices[v].data); for(u=0;ufor(x=v;x<g.vexnum+v;x++){int a;a=x;a=a%g.vexnum;if(!visited[a]){DFS(g,a);count[v]++;}}printf("\n");}int min;min=count[0];for(int i=0;i<g.vexnum;i++){if(min>count[i])min=count[i];}if(min!=1)printf("\n该有向图是不连通图!连通分量为:%d\n",min);elseprintf("\n该有向图是连通图!\n");return OK;}/*---------------------返回当前有向图中的每个顶点的入度与出度----------------*///图中某个顶点的入度status InDegree(ALGraph G,int i){int j;int n=0;for(j=0;j<g.vexnum;j++){if(GraphExist(G,j,i)) n++;}return n;}//图中某个顶点的出度status OutDegree(ALGraph G,int i){ArcNode *p;int j=0;p=G.vertices[i].firstarc;while(p!=NULL){j++;p=p->nextarc;}return j;}//每个顶点的与出度入度void degree(ALGraph G){int i,n,m;char a;for(i=0;i<g.vexnum;i++){a=G.vertices[i].data;n=InDegree(G,i);m=OutDegree(G,i);printf("顶点%c的入度是%d,出度是%d\n",a,n,m);}}/*-------------------------------当前有向图插入弧-----------------------*/int GraphAdd(ALGraph &G){int n,k,i,j,w;ArcNode *p;VertexType v1,v2;k=G.vexnum*(G.vexnum-1)-G.arcnum;printf("请输入要增加的弧数:");scanf("%d",&n);while(n>k){printf("\n输入有误,增加的边数不能超过%d,请重新输入!",k); printf("\n请输入有向图的边数:");scanf("%d",&n);}for(k=0;k<n;k++){getchar();printf("请输入要增加的弧的起点与终点(用逗号分隔):"); scanf("%c,%c",&v1,&v2);i=locateALG(G,v1);j=locateALG(G,v2);if(i<0||j<0||i==j||GraphExist(G,i,j)){printf("输入</n;k++){</g.vexnum;i++){</g.vexnum;j++){</g.vexnum;i++){</g.vexnum+v;x++){</g.vexnum;v++){有误,请重新输入\n");k--;continue;}printf("请输入第%d条弧的权值:",k+1);scanf("%d",&w);p=new ArcNode;p->adjvex=j;p->weight=w;p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;G.arcnum++;printf("插入弧成功\n");}return 1;}/*--------------------------当前有向图中插入顶点-----------------------*/int NodeAdd(ALGraph &G){int i,l,n;char c;printf("请输入要增加的顶点个数:");scanf("%d",&n);//增加的定点个数判断if(G.vexnum+n>MAX_VERTEX_NUM){printf("输入错误,最多有50个顶点\n");return ERROR;}for(i=0;igetchar();printf("请输入要增加的顶点:");scanf("%c",&c);l=locateALG(G,c);if(l>=0){printf("输入的顶点重复,请重新输入\n");i--;continue;}G.vertices[G.vexnum].data=c;G.vertices[G.vexnum].firstarc=NULL;G.vexnum++;printf("增加顶点成功\n");}return OK;}/*---------------------------当前有向图删除弧-------------------*/int delArc(ALGraph &G,int i,int j){ArcNode *p,*q;p=G.vertices[i].firstarc;if(p->adjvex==j){G.vertices[i].firstarc=p->nextarc;free(p);}else{while(p->nextarc&&p->nextarc->adjvex!=j)p=p->nextarc;if(p){q=p->nextarc;p->nextarc=q->nextarc;free(q);}}G.arcnum--;return OK;}int GraphDel(ALGraph &G){int n,k,i,j;VertexType v1,v2;printf("请输入要删除的弧数:");scanf("%d",&n);while(n>G.arcnum){printf("删除的弧数不能超过%d,请重新输入\n",G.arcnum); printf("请输入要删除的弧数:");scanf("%d",&n);}for(k=0;k<n;k++){getchar();printf("请输入要删除的弧的起点与终点(用逗号分隔):"); scanf("%c,%c",&v1,&v2);i=locateALG(G,v1);j=locateALG(G,v2);if(i<0||j<0||i==j||(!GraphExist(G,i,j))){printf("输入有误,请重新输入\n");k--;continue;}delArc(G,i,j);}return 1;}/*---------------------------当前有向图删除顶点-------------------*/int NodeDel(ALGraph &G){int i,l,n,k;char c;ArcNode *p;printf("请输入要删除的顶点个数:");scanf("%d",&n);if(n>G.vexnum){printf("输入错误\n");return ERROR;}for(k=0;kgetchar();printf("请输入要删除的顶点:");scanf("%c",&c);l=locateALG(G,c);if(l<0){printf("输入的顶点不存在,请重新输入\n");k--;continue;}for(i=0;i<g.vexnum;i++){//删除与此顶点相关的弧if(GraphExist(G,i,l)){delArc(G,i,l);}if(GraphExist(G,l,i)){delArc(G,l,i);}//修改必要表结点的顶点的位置值p=G.vertices[i].firstarc;while(p){if(p->adjvex>l){ p->adjvex--;}p=p->nextarc;}}//释放空间,顶点c后的顶</g.vexnum;i++){</n;k++){点前移for(i=l;i<g.vexnum-1;i++){G.vertices[i]=G.vertices[i+1];}G.vexnum--;printf("删除顶点成功\n");}return OK;}/*--------------------------存储结构的转换-----------------------*///将邻接表转换成邻接矩阵status TranlateAl(ALGraph G1, MGraph &G2){//设置参数int i,j;ArcNode *p;G2.kind = G1.kind;G2.vexnum = G1.vexnum;G2.arcnum = G1.arcnum;//复制顶点for(i=0;i<g1.vexnum;i++)G2.vexs[i] = G1.vertices[i].data;//复制弧for(i=0;i<g2.vexnum;i++)for(j=0;j<g2.vexnum;j++)G2.arcs[i][j].adj=MAX;for(i=0;ip=G1.vertices[i].firstarc;while(p){G2.arcs[i][p->adjvex].adj=p->weight;p=p->nextarc;}}printf("转换成功\n");return OK;}//将邻接矩阵转换成邻接表status TranlateDG(MGraph G1,ALGraph &G2){ int i,j;ArcNode *p;//设置参数G2.kind= G1.kind;G2.vexnum = G1.vexnum;G2.arcnum = G1.arcnum;//复制顶点for(i=0;i<g1.vexnum;i++){G2.vertices[i].data=G1.vexs[i];G2.vertices[i].firstarc=NULL;}//复制弧for(i=0;i<g1.vexnum;i++){for(j=0;j<g1.vexnum;j++){if(G1.arcs[i][j].adj!=MAX){p=(ArcNode*)malloc(sizeof(ArcNode));//建立结点if(!p) return ERROR;p->weight=G1.arcs[i][j].adj;p->adjvex=j;p->nextarc=G2.vertices[i].firstarc;//顶点i的链表G2.vertices[i].firstarc=p;//添加到最左边}}}printf("转换成功\n");return OK;}/*-----------------深度优先生成树-------------------*/char GetVex(ALGraph G,int i){return G.vertices[i].data;}void DFSTree(ALGraph G,int i, CSTree &T){//从第i个顶点出发深度优先遍历有向图G,建立以T为根的生成树int w;CSNode *p,*q;visited[i]=true;bool first=true;for(w=FirstAdjVex(G,i);w>=0;w=NextAdjVex(G,i)) if(!visited[w]){p=(CSTree)malloc(sizeof(CSNode));p->data=GetVex(G,w);p->firstchild=NULL;p->nextsibling=NULL;if(first){ //w是i的第一个未被访问的邻接顶点T->firstchild=p;//是根的左孩子结点first=false;}else{ //w是i的其他未被访问的邻接顶点q->nextsibling=p; //是上一邻接顶点的右兄弟结点}q=p;DFSTree(G,w,q);}}status DFSforest(ALGraph G,CSTree &T){//建立有向图的深度优先生成森林/生成树int i;CSNode *p,*q;T=NULL;for(i=0;ifor(i=0;i<g.vexnum;i++)if(!visited[i]){ //第i顶点为新的生成树的根节点p=(CSTree)malloc(sizeof(CSNode));p->data=GetVex(G,i);p->firstchild=NULL;p->nextsibling=NULL;if(!T) T=p; //是第一棵生成树的根(T的根)else q->nextsibling=p; //是其他生成树的根q=p; //q指示当前生成树的根DFSTree(G,i,p); //建立以p为根的生成树}printf("图的</g.vexnum;i++)</g1.vexnum;j++){</g1.vexnum;i++){</g1.vexnum;i++){</g2.vexnum;j++)</g2.vexnum;i++)</g1.vexnum;i++)</g.vexnum-1;i++){深度优先生成森林成功\n");return OK;}//树的先根遍历void Preorder(CSTree T){if (!T) return;printf("%c\t",T->data); // 访问根结点Preorder(T->firstchild); // 遍历左子树Preorder(T->nextsibling); // 遍历右子树}/*---------------------是否存在路径,并输出一条简单路径-------------------*///判断有向图G中顶点i到顶点j是否有路径status DfsReachable(ALGraph g, int i, int j){int n,k;LinkQueue Q;ArcNode *p;char v,v1;InitQueue(Q);v1=g.vertices[i].data;EQueue(Q,v1);while(!QueueEmpty(Q)){ //队列不空时循环DeQueue(Q,v);n=locateALG(g,v);visited[n]=true;for(p=g.vertices[n].firstarc;p;p=p->nextarc){ k=p->adjvex;v=g.vertices[k].data;if(j==k){return 1;}if(!visited[k]){EQueue(Q,v);}}}return 0;}//找简单路径bool found;void reacher(ALGraph G,int i,int j,SqStack &s){ VertexType v;int w;ArcNode *p;visited[i]=true;v=G.vertices[i].data;Push(s,v);for(p=G.vertices[i].firstarc;p;p=p->nextarc){ int k=p->adjvex;if(!found){v=G.vertices[k].data;if(j==k){found=true;Push(s,v);break;}elseif(!visited[k]){reacher(G,k,j,s);}}}if(!found){Pop(s,v);}}int exist_path(ALGraph G){SqStack s;InitStack(s);int n,i,j;VertexType v1,v2;found=false;for(n=0;n<g.vexnum;n++)visited[n]=false;printf("请输入起点与终点(用逗号分隔):");getchar();scanf("%c,%c",&v1,&v2);i=locateALG(G,v1);j=locateALG(G,v2);if (i<0||j<0||i==j){printf("输入错误\n");return -1;}if(DfsReachable(G,i,j)){for(n=0;n<g.vexnum;n++)visited[n]=false;reacher(G,i,j,s);printf("顶点%c到顶点%c存在路径,其一条简单路径为:",v1,v2);Get(s);DestroyStack(s);}elseprintf("顶点%c到顶点%c不存在路径\n",v1,v2);return OK;}/*--------------------------拓扑排序判断是否存在环--------------*/status ToplogicalSort(ALGraph G){char v;LinkQueue Q;ArcNode *p;int k;int i,j;int n=G.vexnum;int indegree[21];for(i=0;i<n;i++)indegree[i]=InDegree(G,i);InitQueue(Q);for(i=0;i<n;i++){if(!indegree[i]){v=G.vertices[i].data;EQueue(Q,v);}}int count=0; //对输出顶点计数while (!QueueEmpty(Q)){DeQueue(Q,v);++count;j=locateALG(G,v);for(p=G.vertices[j].firstarc;p;p=p->nextarc){ k=p->adjvex;--indegree[k]; // 弧头顶点的入度减1if(!indegree[k]){v=G.vertices[k].data;EQueue(Q,v);}}}//whileif (count<n){printf("此有向图中存在环\n");return ERROR;}printf("此有向图中不存在环\n");return OK;}/*---------------------源点到其他顶点的最短路径----------------------*/int prev[50];//p</n){</n;i++){</n;i++)</g.vexnum;n++)</g.vexnum;n++)rev[v]表示从源s到顶点v的最短路径上顶点的前驱顶点。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
p->mark=unvisited; /* 设初值 */
p->ivex=i;
p->ilink=(*G).adjmulist[i].firstedge; /* 插在表头 */
(*G).adjmulist[i].firstedge=p;
p->jvex=j;
{
scanf("%s",(*G).adjmulist[i].data);
(*G).adjmulist[i].firstedge=NULL;
}
printf("请顺序输入每条边的两个端点(以空格作为间隔):\n");
for(k=0;k<(*G).edgenum;++k) /* 构造表结点链表 */
while(p)
if(p->ivex==i&&p->jvex!=j) /* 不是邻接顶点w(情况1) */
p=p->ilink; /* 找下一个邻接顶点 */
else if(p->jvex==i&&p->ivex!=j) /* 不是邻接顶点w(情况2) */
{
scanf("%s%s%*c",va,vb); /* %*c吃掉回车符 */
i=LocateVex(*G,va); /* 一端 */
j=LocateVex(*G,vb); /* 另一端 */
p=(EBox*)malloc(sizeof(EBox));
return OK;
}
Status InsertArc(AMLGraph *G,VertexType v,VertexType w)
{ /* 初始条件:无向图G存在,v和W是G中两个顶点。操作结果:在G中增添弧<v,w> */
int i,j;
EBox *p;
i=LocateVex(*G,v); /* 一端 */
/* 操作结果:返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1 */
int i;
i=LocateVex(G,v);
if(i<0) /* G中不存在顶点v */
return -1;
if(G.adjmulist[i].firstedge) /* v有邻接顶点 */
}LinkQueue;
int LocateVex(AMLGraph G,VertexType u)
{ /* 初始条件:无向图G存在,u和G中顶点有相同特征 */
/* 操作结果:若G中存在顶点u,则返回该顶点在无向图中位置;否则返回-1 */
int i;
for(i=0;i<G.vexnum;++i)
p=p->jlink; /* 找下一个邻接顶点 */
else /* 是邻接顶点w */
break;
if(p&&p->ivex==i&&p->jvex==j) /* 找到邻接顶点w(情况1) */
{
p=p->ilink;
if(p&&p->ivex==i)
}xType v)
{ /* 初始条件:无向图G存在,v和G中顶点有相同特征 */
/* 操作结果:在G中增添新顶点v(不增添与顶点相关的弧,留待InsertArc()去做) */
if((*G).vexnum==MAX_VERTEX_NUM) /* 结点已满,不能插入 */
/* c1.h (程序名) */
#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdlib.h> /* atoi() */
typedef char VertexType[MAX_NAME]; /* 字符串类型 */
/*课本166页无向图的邻接多重表存储表示 */
#define MAX_VERTEX_NUM 30 //最大顶点30
typedef enum{unvisited,visited}VisitIf;
typedef struct EBox /*边集*/
{
VisitIf mark; /* 访问标记 */
int ivex,jvex; /* 该边依附的两个顶点的位置 */
struct EBox *ilink,*jlink; /* 分别指向依附这两个顶点的下一条边 */
if(p&&p->ivex==i)
return p->jvex;
else if(p&&p->jvex==i)
return p->ivex;
}
return -1;
}
Status PutVex(AMLGraph *G,VertexType v,VertexType value)
}VexBox;
typedef struct /*图 */
{
VexBox adjmulist[MAX_VERTEX_NUM];
int vexnum,edgenum; /* 无向图的当前顶点数和边数 */
EBox *p;
printf("请输入无向图的(顶点数,边数): ");
scanf("%d,%d",&(*G).vexnum,&(*G).edgenum);
printf("请输入%d个顶点的值(<%d个字符):\n",(*G).vexnum,MAX_NAME);
for(i=0;i<(*G).vexnum;++i) /* 构造顶点向量 */
j=LocateVex(*G,w); /* 另一端 */
if(i<0||j<0||i==j)
return ERROR;
p=(EBox*)malloc(sizeof(EBox));
p->mark=unvisited;
p->ivex=i;
p->ilink=(*G).adjmulist[i].firstedge; /* 插在表头 */
return OK;
}
Status DeleteArc(AMLGraph *G,VertexType v,VertexType w)
{ /* 初始条件:无向图G存在,v和w是G中两个顶点。操作结果:在G中删除弧<v,w> */
return p->jvex;
else if(p&&p->jvex==i)
return p->ivex;
}
if(p&&p->ivex==j&&p->jvex==i) /* 找到邻接顶点w(情况2) */
{
p=p->jlink;
InfoType *info; /* 该边信息指针,可指向权值或其他信息 */
}EBox;
typedef struct /*顶点集*/
{
VertexType data;
EBox *firstedge; /* 指向第一条依附该顶点的边 */
if(strcmp(u,G.adjmulist[i].data)==0)
return i;
return -1;
}
void CreateGraph(AMLGraph *G)
{ /* 采用邻接多重表存储结构,构造无向图G */
int i,j,k;
VertexType va,vb;
}AMLGraph;
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front,rear; /* 队头、队尾指针 */
(*G).adjmulist[i].firstedge=p;
p->jvex=j;
p->jlink=(*G).adjmulist[j].firstedge; /* 插在表头 */
(*G).adjmulist[j].firstedge=p;
(*G).edgenum++;
if(G.adjmulist[i].firstedge->ivex==i)
return G.adjmulist[i].firstedge->jvex;
else
return G.adjmulist[i].firstedge->ivex;
else
#define OK 1
#define ERROR 0
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int InfoType; /* 权值类型 */
typedef int QElemType;
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
{ /* v赋新值value */
int i;
i=LocateVex(*G,v);
if(i<0) /* v不是G的顶点 */
相关文档
最新文档