数据结构(有-无向网-图)

合集下载

第7章 图-有向无环图

第7章 图-有向无环图

算法的执行步骤: 算法的执行步骤: 1、用一个数组记录每个结点的入度。将入度为零的 、用一个数组记录每个结点的入度。 结点进栈。 结点进栈。 2、将栈中入度为零的结点V输出。 、将栈中入度为零的结点 输出 输出。 3、根据邻接表找到结点 的所有的邻接结点, 并将 、根据邻接表找到结点V的所有的邻接结点 的所有的邻接结点, 这些邻接结点的入度减一。 这些邻接结点的入度减一 。 如果某一结点的入度变 为零,则进栈。 为零,则进栈。
3
2
3、找到全为零的第 k 列,输出 k 、 4、将第 k 行的全部元素置为零 、 行的全部元素置为零
…………………
7
53、4;直至所有元素输出完毕。 、 ;直至所有元素输出完毕。
1 2 3 4 5 6 7
0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0
template<class T> int BinaryTree <T>:: NumOfOne ( node <T> *t )
{ int k=0; if (t==NULL ) //空二叉树 //空二叉树 return 0; if (t所指结点 的度为 k=1 所指结点 的度为1) k=1; d1= NumOfOne ( t->lchild); //递归求左子树叶结点数 //递归求左子树叶结点数 d2= NumOfOne ( t->rchild); } //递归求右子树叶结点数 //递归求右子树叶结点数 return (d1+d2+k);
A B
AOE网络:结点为事件,有向边指向表示事件的执行次序。 网络:结点为事件,有向边指向表示事件的执行次序。 网络 有向边定义为活动,边的权值为活动进行所需要的时间。 有向边定义为活动,边的权值为活动进行所需要的时间。

数据结构——图思维导图-高清简单脑图模板-知犀思维导图

数据结构——图思维导图-高清简单脑图模板-知犀思维导图

数据结构——图图的定义和基本术语
定义是由一个顶点集V和一个顶点间的关系集合组成的数据结构
分类
有向图
无向图
基本术语
有(无)向网弧或边带权的图
子图
完全图含有e=n(n-1)/2条边的无向图
有向完全图含有e=n(n-1)条弧的有向图
稀疏图边或弧的个数<nlogn
稠密图边或弧的个数>=nlogn
度(入度+出度)
入度以顶点v为弧尾的弧的数目
出度以顶点v为弧头的弧的数目
路径长度路径上边的数目
连通图图中任意两个顶点之间都有路径相通
图的遍历
深度优先搜索DPS
类似于先序遍历
实质对每个顶点查找其邻接点的过程
广度优先搜索BFS实质通过边或弧找邻接点的过程
图的存储结构
邻接矩阵
有向图:对称统计第i行1的个数可得顶点i的出度
无向图:不对称统计第j列1的个数可得顶点j的入度
邻接表只存储图中已有的弧或边的信息
有向图的十字链表将有向图的邻接表和逆邻接表结合起来的一种链
图的应用
最小生成树
普里姆(Prim)算法
贪心算法
最短路径
Dijkstra算法
Floyd算法
拓扑排序
关键路径。

第7章图_数据结构

第7章图_数据结构

v4
11
2013-8-7
图的概念(3)
子图——如果图G(V,E)和图G’(V’,E’),满足:V’V,E’E 则称G’为G的子图
2 1 4 3 5 6 3 5 6 1 2
v1 v2 v4 v3 v2
v1 v3 v4
v3
2013-8-7
12
图的概念(4)
路径——是顶点的序列V={Vp,Vi1,……Vin,Vq},满足(Vp,Vi1),
2013-8-7 5
本章目录
7.1 图的定义和术语 7.2 图的存储结构

7.2.1 数组表示法 7.2.2 邻接表 ( *7.2.3 十字链表 7.3.1 深度优先搜索 7.3.2 广度优先搜索 7.4.1 图的连通分量和生成树 7.4.2 最小生成树
*7.2.4 邻接多重表 )
7.3 图的遍历
连通树或无根树
无回路的图称为树或自由树 或无根树
2013-8-7
18
图的概念(8)
有向树:只有一个顶点的入度为0,其余 顶点的入度为1的有向图。
V1 V2
有向树是弱 连通的
V3
V4
2013-8-7
19
自测题
7. 下列关于无向连通图特性的叙述中,正确的是
2013-8-7
29
图的存贮结构:邻接矩阵
若顶点只是编号信息,边上信息只是有无(边),则 数组表示法可以简化为如下的邻接矩阵表示法: typedef int AdjMatrix[MAXNODE][MAXNODE];
*有n个顶点的图G=(V,{R})的邻接矩阵为n阶方阵A,其定 义如下:
1 A[i ][ j ] 0
【北方交通大学 2001 一.24 (2分)】

算法与数据结构课设(有向图,无向图,有向网,无向网)

算法与数据结构课设(有向图,无向图,有向网,无向网)

算法与数据结构课程设计报告系(院):计算机科学学院专业班级:教技1001姓名:李##学号: ******### 指导教师:***设计时间:2012.6.16 - 2012.6.24设计地点:4号楼2号机房目录一、设计方案 (1)二、实现过程以及代码 (2)三、测试 (20)四、结论和分析 (23)五、难点和收获 (23)一、 设计方案1.程序设计基本过程:拿到课程设计任务书,按照要求,需要设计有向图、有向网、无向图 、无向网四种图,以及邻接矩阵、邻接表两种数据存储结构,三层以上的显示菜单。

图的操作中又包含了有关线性表、栈和队列的基本操作。

由于显示菜单已给出,剩下的任务就是把函数写入其中。

2.程序流程图:预定义 定义结构体 定义变量 各种函数3.程序设计的原理:图的操作都是以两种存储结构为基础的:邻接矩阵存储结构和邻接表存储结构,如有向图,有向网,无向图,无向网的创建,其他的操作都是在四种图创建后才开始进行的。

所以,首先必须理解两种存储结构的定义。

图的邻接矩阵存储结构即图的数组表示法。

用两个数组分别存储数据元素(如顶点)的信息和数据元素之间的关系(如边或弧)的信息。

用邻接矩阵存储结构的图具有以下几点特征:(一):顶点数:vexnum ,边(弧)数:arcnum ,图的种类:kind ;(二):邻接矩阵:arcs(1顶点关系类型:adj 2相关信息:*info);(三):顶点向量(顶点名):vexs[];其优点是以二维数组表示有n 个顶点的图时,需存放n 个顶点的信息和n*n 条弧的信息存储量。

借助邻接矩阵容易判定任意两个顶点之间是否有边或弧相连,并容易求出各个顶点的度。

缺点是时间复杂度是O (n*n ),例如,构造一个具有n 个顶点和e 条边的无向网的时间复杂度为O (n*n+e*n )。

图的邻接表存储结构是图的一种链式存储结构。

对图中的每个顶点建立一个单链表,每个结点由三个域组成,邻接点域adjvex (弧尾在邻接表链表中的位序),链域nextarc (下一条弧),数据域info(权值)。

有向无环图

有向无环图

有向无环图有向无环图(DAG)是一种重要的图形数据结构,在计算机科学、网络和算法分析等领域中都有广泛的应用。

它与普通无向图有所不同,因为它会在连接时增加一个方向,这就意味着它可以表示有序的数据。

有向无环图被广泛应用于计算机科学领域,比如拓扑排序、分布式处理、编译器设计等等。

概念有向无环图是由一些顶点和一些有序的边组成,它将数据结构中的每个顶点连接起来。

每条边都有一个方向,这就决定了图中的有序性,也决定了如何遍历图中的每个顶点。

它只有在没有重复出现的边时,才能保证从一个顶点开始,能够遍历到整个图中的每个顶点。

另外一个特点是,它不能有环,也就是说,从一个顶点出发,不能回到该顶点本身。

拓扑排序有向无环图是一种很强大的数据结构,它可以用来实现拓扑排序(Topological Sorting)。

拓扑排序是一种重要的技术,可以根据有向边的方向,对顶点进行排序,以便给定时序性任务分配排序方式。

比如,在建筑工程中,需要用到拓扑排序,比如地基建完再搭框架,搭框架后再安装门窗等等。

拓扑排序能保证输出的顺序和输入的顺序一致,也可以用于求解最短路径问题,比如求解从一个城市到另外一个城市的最短路径。

分布式处理有向无环图也可以用来实现分布式处理(Distributed Processing),它可以把任务分解成一些独立的子任务,然后把它们连接起来,形成有向无环图,这样每一个子任务可以在不同的处理器上完成。

分布式处理可以使用有向无环图的拓扑排序算法,实现对任务的排序,从而保证任务的正确执行。

同时,由于它不存在环路,因此也可以保证它是安全的,不会出现死锁的情况,这样也就可以保证流程的有序性。

编译器设计有向无环图也可以用于编译器设计(Compiler Design)。

编译器是计算机科学中一种重要的应用,它可以把高级语言翻译成机器语言,从而可以让计算机处理高级语言编写的程序。

有向无环图可以用来构建编译器,因为它可以实现对语句的排序,这样可以保证编译器在编译过程中符合语法规则,并且能够正确翻译,从而使程序能够正确执行。

数据结构-图

数据结构-图
回退到C,C 的4 个邻接顶点中还有D 和G 没有访问,选择一个顶点,例如以D 作为新的
出发点,访问D,标注数字序号④;
(a)无向图 G9
(b)深度优先遍历
图的遍历
3.1图的深度优先遍历
接着到G,访问G, 标注数字序号⑤;G 相邻顶点都访问过了,顺着虚线箭头方向
回退到 D,D 相邻顶点都访问过了,顺着虚线箭头方向回退到C,C 相邻顶点也都访问过
图的基本概念
1.2图的操作定义
02
PART
图的存储结构
2.1邻接矩阵
首先介绍的是数组表示法,即用两个数组分别存储顶点的信息和顶点之间的关系。
用来存放图中 n 个顶点的数组称为顶点数组。我们可将图中顶点按任意顺序保存到顶点数组中,
这样按存放次序每个顶点就对应一个位置序号(简称位序),依次为0~n-1;接着用一个 n×n 的二维
称为有向图。例如,当V={v1,v2,v3,v4,v5},VR={<v1,v2>,
<v1,v4>,<v2,v4>,<v3,v1>,<v3,v5>,<v4,v3>,<v5,v4>},则顶点集合
V、关系集合VR 构成有向图G1=(V,VR),如图(a)所示。
图的基本概念
1.1图的定义与基本术语
无向图(Undirected Graph)。如果顶点间的关系是无
序号作为表结点的值,所以一条弧对应一个表结点。右图为有向图 G1
和无向图 G2的邻接表表示法存储示意图。
图的存储结构
2.2邻接表
对于有向网和无向网,由于表结点表示边或弧,因此需要对表结点扩充一个属性域,表
结点至少包含顶点序号、权值和下一表结点指针 3 个属性,由此构成网的邻接表。

数据结构图

数据结构图

所以:对于点多边少的稀疏图来说,采用邻接表 结构使得算法在时间效 率上大大提高。
16
3/12
广度优先搜索(Breadth First Search,简称BFS ) BFS类似于树的层序遍历; 用一个数组用于标志已访问与否,还需要一个工作队列。
【例】一个无向图的BFS
8
6
CD
4
7
HG
BA
邻接多重表(Adjacency Multilist)
9
边表
• 在某些应用中,有时主要考察图中边的权值以及所依附的 两个顶点,即图的结构主要由边来表示,称为边表存储结 构。
• 边表结构采用顺序存储,用2个一维数组构成,一个存储 顶点信息,一个存储边的信息。边数组的每个元素由三部 分组成:
– 边的起点下标 – 边的终点下标 – 边的权值
1
A [i][
j]


0
如果 (vi , v j ) 或 vi , v j G的边 其它
无权图的邻接矩阵表示示例
V1
V2
V0
3
V3
4 12/15
带权图的邻接矩阵的定义
A [i][ j] wij
如果 (vi , vj ) 或 vi , v j G的边 其它
带图权的图邻的接邻矩接阵矩表阵示表示示例示[例例6.9]
1
第一部分 图的定义和术语
2
图的定义
“图” G可以表示为两个集合:G =(V, E)。每条 边是一个顶点对(v, w) E ,并且 v, w V。
通常:用 |V| 表示顶点的数量(|V| ≥ 1), 用 |E| 表示边的数量(|E| ≥ 0)。
(1) 无向图(完全有向图边数与顶点数之间的 关系) (2) 有向图(完全有向图弧数与顶点数之间的 关系) (3) 简单图:没有重边和自回路的图 (4) 邻接 (5) 路径,路径长度 (6) 无环(有向)图:没有任何回路的(有向)图 (7) 度,入度,出度 (8) 无向图的顶点连通、连通图、连通分量 (9) 有向图的顶点强连通,强连通图、连通分量

数据结构学位考3

数据结构学位考3

V1
V2
V3
V4
有向图
V1 V2
V3 V4 V5
无向图

顶点数n和边(弧)的数目e:

无向图:
0e

有向图: e n(n 1) 0
1 n(n 1) 2



完全图:有n(n-1)/2条边的无向图; 有向完全图:有n(n-1)条弧的有向图; 稀疏图、稠密图 子图:G=(V,{E}),G’=(V’,{E’}),若V’ V,且E’ E,则称G’为 G的子图 邻接点:无向图中,(v,v’)∈E,则v,v’互为邻接点; 顶点v的度:与v相关联的边的数目,TD(v) 有向图中,若<v,v’>∈A,则顶点v邻接到顶点v’,而顶点v’邻接 自v 出度:以v为尾的弧的数目,OD(v) 入度:以v为头的弧的数目,ID(v) TD(v)=OD(v)+ID(v)

有向图:如果有一个顶点的入度为0,其余顶点的入 度都为1,则是一棵有向树。
A C F B
J L M
图的存储结构

数组表示法(邻接矩阵): 用两个数组分别存放顶点信息和边 (弧)信息
V1 V2
G1.VEXS[4]=[V1 V2 V3 V4]
G1.arcs=
0 0 0 1
0 1 0 1 0 1 0 1 0 1

路径:

回路(环) 简单路径:顶点序列中顶点不重复的路径。

连通图、连通分量、强连通图、强连通分量:
A C F G I L H K D E
B
A
C
B
D
E
F
I J M L M
G
H
K
J

数据结构-图及其存储结构

数据结构-图及其存储结构
//不含其他信息 for (i=0;i<G.vexnum;+ +i ) scanf(G.vexs[i]); //一维数组存放顶点值 for (i=0;i<G.vexnum;+ +i ) //二维数组赋初值
for (j=0;j<G.vexnum;+ +j ) adj Info G.arcs[i][j]={∞,NULL}; //Arccell的形式为: for (k=0;k<G.arcnum;+ +i ) { //二维数组存放各边上的信息 scanf(v1,v2,w); i=locatevex(G,v1); j=locatevex(G,v2); //求顶点v1,v2在图中的位置 G.arcs[i][j].adj=w; G.arcs[j][i].adj=w; //无向网的邻接矩阵是对称的 if (IncInfo) Input (*G.arcs[i][j].info); //将弧上的信息存储在指针info
case UDN: return CreateUDN(G);
default : return ERROR; }//CreateGraph
二、存储结构
2.数组表示法前提下图的输入
*以无向网为例,即当用户输入图的类型标志为UDN时,有:
Status CreateUDN(MGraph &G){ scanf(G.vexnum,G.arcnum,IncInfo); //IncInfo 为0时表示各弧
v2 6 5
v1 5 1 5 v3 3 6 4 2 v4
一个连通无向图的生成树是该图的一个连通分量,它 包含有该图的所有n个顶点以及连接这n个顶点的(n-1) 条边。 边或弧上带权值的图称为带权图或网(分为无向网和 有向网)。 一个无向图的所有生成树中,边上的权值之和最小的 生成树称为该图的最小生成树或最小代价生成树。

数据结构-第7章图答案

数据结构-第7章图答案

7.3 图的遍历 从图中某个顶点出发游历图,访遍图中其余顶点, 并且使图中的每个顶点仅被访问一次的过程。 一、深度优先搜索 从图中某个顶点V0 出发,访问此顶点,然后依次 从V0的各个未被访问的邻接点出发深度优先搜索遍 历图,直至图中所有和V0有路径相通的顶点都被访 问到,若此时图中尚有顶点未被访问,则另选图中 一个未曾被访问的顶点作起始点,重复上述过程, 直至图中所有顶点都被访问到为止。
void BFSTraverse(Graph G, Status (*Visit)(int v)) { // 按广度优先非递归遍历图G。使用辅助队列Q和访问标志数组 visited。 for (v=0; v<G.vexnum; ++v) visited[v] = FALSE; InitQueue(Q); // 置空的辅助队列Q for ( v=0; v<G.vexnum; ++v ) if ( !visited[v]) { // v尚未访问 EnQueue(Q, v); // v入队列 while (!QueueEmpty(Q)) { DeQueue(Q, u); // 队头元素出队并置为u visited[u] = TRUE; Visit(u); // 访问u for ( w=FirstAdjVex(G, u); w!=0; w=NextAdjVex(G, u, w) ) if ( ! visited[w]) EnQueue(Q, w); // u的尚未访问的邻接顶点w入队列Q
4。邻接多重表
边结点
mark ivex
顶点结点
ilink
jvex
jlink
info
data
firstedge
#define MAX_VERTEX_NUM 20 typedef emnu {unvisited, visited} VisitIf; typedef struct Ebox { VisitIf mark; // 访问标记 int ivex, jvex; // 该边依附的两个顶点的位置 struct EBox *ilink, *jlink; // 分别指向依附这两个顶点的下一条 边 InfoType *info; // 该边信息指针 } EBox; typedef struct VexBox { VertexType data; EBox *firstedge; // 指向第一条依附该顶点的边 } VexBox; typedef struct { VexBox adjmulist[MAX_VERTEX_NUM]; int vexnum, edgenum; // 无向图的当前顶点数和边数 } AMLGraph;

《数据结构之图》相关知识点总结

《数据结构之图》相关知识点总结

第5章图●图的定义①图由顶点集V和边集E组成,记为G=(V,E),V(G)是图G中顶点的有穷非空集合,E(G)是图G中顶点之间变得关系集合,|V|表示顶点个数,也称图的阶,|E|表示边数(线性表和树都可以是空的,但图可以只有一个顶点没有边)②有向图:弧是顶点的有序对,记为<v,w>,v,w是顶点,v是弧尾,w是弧头,从顶点v到顶点w的弧。

无向图:边是顶点的无序对,记为(v,w)③简单图:一个图满足:不存在重复边;不存在顶点到自身的边。

多重图相对于简单图定义④完全图:无向图中,任意两顶点之间存在边,称为完全无向图。

N个顶点的无向完全图有n(n-1)/2条边。

在有向图中,任意两顶点之间存在方向相反的两条弧,称为有向完全图,N 个顶点的有向完全图有n(n-1)条边。

⑤连通图:在无向图中任意两顶点都是连通的。

无向图中的极大连通子图称为连通分量。

极大要求连通子图包含其所有的边和顶点,极小连通子图既要保持图连通,又要保持边数最少⑥在有向图中任意两顶点v,w,存在从顶点v到顶点w和从顶点w到顶点v两条路径,这种图称为强连通图。

有向图的极大强连通子图称为有向图的强连通分量。

⑦生成树:①包含图中所有顶点n,②生成树有n-1条边, ③任意两点连通。

对生成树而言,砍去一条边变成非连通图,加上一条边形成一个回路。

在非连通图中,连通分量的生成树构成了非连通图的生成森林。

⑧顶点的度:以该顶点为端点的边的数目。

无向图的全部顶点的度之和等于边数的两倍。

有向图的度等于出度和入度之和,入度是以该顶点为终点的有向边的数目,出度是以该顶点为起点的有向边的数目。

有向图的全部顶点的入度之和和出度之和相等且等于边数。

⑨图中每条边可以标上具有某种含义的数值,该数值称为边的权值。

带有权值的图称为网。

○10对于无向图G=(V, {E}),如果边(v,v’)∈E,则称顶点v,v’互为邻接点,即v,v’相邻接。

边(v,v’)依附于顶点v 和v’,或者说边(v, v’)与顶点v 和v’相关联。

数据结构严蔚敏(全部章节814张PPT)-(课件)

数据结构严蔚敏(全部章节814张PPT)-(课件)
① 集合:结构中的数据元素除了“同属于一个集合” 外,没有其它关系。
② 线性结构:结构中的数据元素之间存在一对一的 关系。
③ 树型结构:结构中的数据元素之间存在一对多的 关系。
④ 图状结构或网状结构:结构中的数据元素之间存 在多对多的关系。
图1-3 四类基本结构图
1.1.3 数据结构的形式定义
数据结构的形式定义是一个二元组: Data-Structure=(D,S)
计算机求解问题的一般步骤
编写解决实际问题的程序的一般过程:
– 如何用数据形式描述问题?—即由问题抽象出一个 适当的数学模型; – 问题所涉及的数据量大小及数据之间的关系; – 如何在计算机中存储数据及体现数据之间的关系? – 处理问题时需要对数据作何种运算? – 所编写的程序的性能是否良好? 上面所列举的问题基本上由数据结构这门课程来回答。
其中:D是数据元素的有限集,S是D上关系的有限集。 例2:设数据逻辑结构B=(K,R)
K={k1, k2, …, k9} R={ <k1, k3>,<k1, k8>,<k2, k3>,<k2, k4>,<k2, k5>,<k3, k9>, <k5, k6>,<k8, k9>,<k9, k7>,<k4, k7>,<k4, k6> } 画出这逻辑结构的图示,并确定那些是起点,那些是终点
<基本操作名>(<参数表>) 初始条件: <初始条件描述> 操作结果: <操作结果描述>
– 初始条件:描述操作执行之前数据结构和参数应 满足的条件;若不满足,则操作失败,返回相应的出 错信息。

数据结构复习与习题解析

数据结构复习与习题解析
❖深度优先搜索
1、访问指定的起始顶点;
2、若当前访问的顶点的邻接顶点有未被访问的,则任选一个访问 之;反之,退回到最近访问过的顶点;直到与起始顶点相通的 全部顶点都访问完毕;
3、若此时图中尚有顶点未被访问,则再选其中一个顶点作为起始 顶点并访问之,转 2; 反之,遍历结束。
4
8/5/2021
例题解析
j va5i
k
v9
v3
v8
(1) 从 ve(1) = 0 开始向前递推
v4 a6=2 v6
ve( j) Max{ve(i) dut( i, j )}, i, j T , 2 j n i
其 中T 是 所 有 以j 为 头 的 弧 的 集 合 。
(2) 从 vl(n) = ve(n) 开始向后递推
8/5/2021
例题解析
❖ 请分别用Prim算法和Kruskal算法构造以下网络的 最小生成树,并求出该树的代价。
9
8/5/2021
ቤተ መጻሕፍቲ ባይዱ
例题解析
【解析】Prim算法的操作步骤:首先从一个只 有一个顶点的集合开始,通过加入与其中顶点 相关联的最小代价的边来扩充顶点集,直到所 有顶点都在一个集合中。
10
22
8/5/2021
例题解析
例:设有一组关键字{32,75,63,48,94,25,36,18,70},采用哈希函数: H(key)=key MOD 11并采用步长为1的线性探测法解决冲突,试在0--10的 散列地址空间中对该关键字序列构造哈希表。
0 1 2 3 4 5 6 7 8 9 10
70
25 48 36 94 18 63 75 32
H(36)=(4+1) MOD 11=5

数据结构_图_采用邻接矩阵存储,构造无向图

数据结构_图_采用邻接矩阵存储,构造无向图

1.采用邻接矩阵(邻接表)存储,构造无向图(网)输入:顶点数、边数、顶点信息、边信息输出:图的顶点,图的边邻接矩阵(数组表示法)处理方法:用一个一维数组存储图中顶点的信息,用一个二维数组(称为邻接矩阵)存储图中各顶点之间的邻接关系。

假设图G=(V,E)有n个顶点,则邻接矩阵是一个n×n 的方阵,定义为:如果(vi,vj)属于边集,则edges[i][j]=1,否则edges[i][j]=0。

邻接表存储的处理方法:对于图的每个顶点vi,将所有邻接于vi的顶点链成一个单链表,称为顶点vi的边表(对于有向图则称为出边表),所有边表的头指针和存储顶点信息的一维数组构成了顶点表。

程序代码:#include<iostream>using namespace std;#define MAX_VERTEX_NUM 20 //最大顶点个数#define OK 1typedef int Status;//图的数组(邻接矩阵)存储表示typedef struct ArcCell { // 弧的定义int adj; // VRType是顶点关系类型。

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

int *info; // 该弧相关信息的指针} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct { // 图的定义char vexs[MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数、弧数} MGraph;int LocateV ex(MGraph G, char v){int a;for (int i = 0; i <= G.vexnum; i++){if (G.vexs[i] == v)a= i;}return a;}Status CreateUDN(MGraph &G) { //采用邻接矩阵表示法,构造无向网Gint i, j, k, w;char v1, v2;cout <<"输入顶点数,边数:"<< endl;cin >> G.vexnum >> G.arcnum;//IncInfo为0,表示各弧无信息cout <<"各顶点分别为:"<< endl;for (i = 0; i<G.vexnum; i++)cin >> G.vexs[i]; //构造顶点向量for (i = 0; i<G.vexnum; i++) //初始化邻接矩阵for (j = 0; j<G.vexnum; j++){G.arcs[i][j].adj =NULL;}cout <<"顶点信息、边信息:"<< endl;for (k = 0; k<G.arcnum; k++) { //构造邻接矩阵cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值i = LocateV ex(G, v1); j = LocateV ex(G, v2);G.arcs[i][j].adj = w;G.arcs[j][i] = G.arcs[i][j];} return OK;} //CreateUDN (p162 算法7.2)Status printf1(MGraph G){cout <<"该图的顶点分别为:";for (int i = 0; i<G.vexnum; i++)cout << G.vexs[i] <<"";return OK;}Status printf2(MGraph G){cout <<"该图的边为:";for (int i = 1; i<G.vexnum; i++) //初始化邻接矩阵for (int j = 0; j<i; j++){if (G.arcs[i][j].adj !=NULL)cout << G.vexs[j]<< G.vexs[i] <<"," ;}return OK;}int main(){MGraph G;CreateUDN(G);printf1(G);cout << endl;printf2(G);cout << endl;system("pause");return 0;}。

算法与数据结构课程设计(有向图,无向图,有向网,无向网)

算法与数据结构课程设计(有向图,无向图,有向网,无向网)

算法与数据结构课程设计报告系(院):计算机科学学院专业班级:教技1001班*名:***学号:*********指导教师:***设计时间:2012.6.16 - 2012.6.24设计地点:4号楼2号机房目录一、设计方案及实现过程******************第3页二、实现代码***********************************第4页三、测试******************************************第19页四、难点与收获********************************第21页一、设计方案及实现过程这次课程设计要求实现无向图、有向图、无向网以及有向网的一些基本操作以及应用,大体的方案是先进入界面后,选择无向图、有向图、无向网、无向网中的一个,然后创建相应的图或者网,创建好后,在此基础上选择进行相关的操作,具体的函数放在main函数前面,通过多次函数调用已达到具体操作的实现。

流程图如下:进入选择界面1 无向图创建无向图1 创建无向图的邻接矩阵函数调用2 创建无向图的邻接表函数调用3无向图的深度优先遍历函数调用4 无向图的广度优先遍历函数调用5 返回选择主界面2 有向图3 无向网4 有向网5 退出有向图、无向网、有向网的操作和无向图类似,在这里不一一列举。

二、实现代码#include<stdio.h># include <stdlib.h># define maxlen 10# define large 999# define true 1# define false 0# define ok 1# define error 0# define overflow -2# define null 0typedef int status;#include <ctype.h>#include <string.h>#include <queue>#include <stack>#include <process.h>using namespace std;#define MAX_VERTEX_NUM 20#define MAX 1000typedef struct{int a[maxlen],b[maxlen],h[maxlen];char vexs[maxlen];int vexnum,arcnum;int kind;int arcs[maxlen][maxlen];}graph;typedef struct node{int adjvex;int info;struct node *next;}edgenode;typedef struct{int id;char data;edgenode *link;}vexnode;typedef struct{vexnode adjs[maxlen];int vexnum,arcnum;int kind;}adjlist;typedef struct qnode{int data;struct qnode *next;}linkqlist;typedef struct{linkqlist *front;linkqlist *rear;} linkqueue;typedef struct{int stack[maxlen];int top;}stackstru;int cnull=-1;graph g;adjlist adjl;stackstru *t;stackstru *s;linkqueue *q;graph printf_adjmatrix(graph g){int i,j;printf("邻接矩阵:\n");printf("vertex\t");for (i=0;i<g.vexnum;i++) printf("%4c",g.vexs[i]);printf("\n");for(i=0;i<g.vexnum;i++){printf("% 4c \t",g.vexs[i]);for(j=0;j<g.vexnum;j++) printf("%4d",g.arcs[i][j]);printf("\n");}return g;}void create_2(graph g){ //构造有向图int i,j,k,c=0;for (i=0;i<g.vexnum;i++)for(j=0;j<g.vexnum;j++)g.arcs[i][j]=c;for(k=0;k<g.arcnum;k++)g.arcs[g.a[k]-1][g.b[k]-1]=1;printf_adjmatrix(g);}void create_1(graph g){ //构造无向图int i,j,k,c=0;for (i=0;i<g.vexnum;i++)for(j=0;j<g.vexnum;j++)g.arcs[i][j]=c;for(k=0;k<g.arcnum;k++){g.arcs[g.a[k]-1][g.b[k]-1]=1;g.arcs[g.b[k]-1][g.a[k]-1]=1;}printf_adjmatrix(g);}graph create_4(graph g){ //构造有向网int i,j,k,c=999;for (i=0;i<g.vexnum;i++)for(j=0;j<g.vexnum;j++)g.arcs[i][j]=c;for(k=0;k<g.arcnum;k++)g.arcs[g.a[k]-1][g.b[k]-1]=g.h[k];printf_adjmatrix(g);return g;}graph create_3(graph g){ //构造无向网int i,j,k,c=999;for (i=0;i<g.vexnum;i++)for(j=0;j<g.vexnum;j++)g.arcs[i][j]=c;for (k=0;k<g.arcnum;k++){g.arcs[g.a[k]-1][g.b[k]-1]=g.h[k];g.arcs[g.b[k]-1][g.a[k]-1]=g.h[k];}printf_adjmatrix(g);return g;}void creategraph(graph g){switch(g.kind){case 1:create_1(g);break;case 2:create_2(g);break;case 3:create_3(g);break;case 4:create_4(g);break;default:printf("Error\n");}}adjlist createlist (graph g ,adjlist adjl){ //创建邻接表int i;edgenode *p;if(g.kind==1||g.kind==3){//创建有向邻接表for(i=0;i<adjl.arcnum;i++){p=(edgenode*)malloc(sizeof(edgenode));p->adjvex=g.b[i];p->info=g.h[i];p->next=adjl.adjs[g.a[i]-1].link;adjl.adjs[g.a[i]-1].link=p;}}if(g.kind==2||g.kind==4){//创建无向邻接表for(i=0;i<adjl.arcnum;i++){p=(edgenode*)malloc(sizeof(edgenode));p->info=g.h[i];p->adjvex=g.b[i];p->next=adjl.adjs[g.a[i]-1].link;adjl.adjs[g.a[i]-1].link=p;p=(edgenode*)malloc(sizeof(edgenode));p->info=g.h[i];p->adjvex=g.a[i];p->next=adjl.adjs[g.b[i]-1].link;adjl.adjs[g.b[i]-1].link=p;}}printf("邻接表为:\n");for(i=0;i<g.vexnum;i++){printf("[%d,%c]=>",i+1,adjl.adjs[i].data);p=adjl.adjs[i].link;while(p!=null){printf("[%c,%d]-->",adjl.adjs[(p->adjvex)-1].data,p->info);p=p->next;}printf("^\n");}return adjl;}void initqueue(linkqueue *p){ //构造空队列p->front=(linkqlist *)malloc(sizeof(linkqlist));p->rear=p->front;(p->front)->next=null;}status empty(linkqueue *q){ //判断是否为空int v;if(q->front==q->rear) v=true;else v=false;return v;}int addqueue(linkqueue *q,int e){q->rear->next=(linkqlist *)malloc(sizeof(linkqlist));q->rear=q->rear->next;if(!q->rear) return -1;q->rear->data=e;q->rear->next=null;return ok;}status delqueue(linkqueue *q){ //linkqlist *p;int e;if (q->front==q->rear)printf("the linklist is overflow");else p=(q->front)->next;(q->front)->next=p->next;e=p->data;if(q->rear==p)q->rear=q->front;free(p);return(e);}bool visit[maxlen]; //深度优先搜索void DFS(adjlist adjl,int i){edgenode *p;visit[i]=1;printf("%c ",adjl.adjs[i].data);for(p=adjl.adjs[i].link;p;p=p->next){if(!visit[p->adjvex]) DFS(adjl,p->adjvex);}}void DFSTraverse(adjlist adjl){int i;printf("\t\t深度优先搜索:");for( i=0;i<maxlen;i++)visit[i]=false;for( i=0;i<=adjl.vexnum;i++)if(!visit[i]) DFS(adjl,i);}queue <int> Q;void BFSTraverse(adjlist adjl) { //广度优先搜索edgenode *w;int i,j;printf("\n\t\t广度优先搜索:");for( i=0;i<maxlen;i++)visit[i]=0;for(i=0;i<=adjl.vexnum;i++){if(!visit[i]){visit[i]=1;printf("%c ",adjl.adjs[i].data);Q.push(i);while(!Q.empty()){j=Q.front();Q.pop();for( w=adjl.adjs[i].link;w;w=w->next)if(!visit[w->adjvex]){visit[w->adjvex]=1;printf("%c ",adjl.adjs[w->adjvex-1].data);Q.push(w->adjvex);}}}}}status initstack(stackstru *s){ //构造空栈s->top=0;return ok;}status push(stackstru *s,int x) { //进栈if (s->top==maxlen)printf("the stack is overflow!\n");else{s->top=s->top+1;s->stack[s->top]=x;}return 1;}status pop(stackstru *s) //出栈{int y;if(s->top==0)printf("the stack is empty!\n");else{y=s->stack[s->top];s->top=s->top-1;}return y;}status stackempty(stackstru *s) //判断栈是否为空{ if (s->top==maxlen) return (true);else return (false);}int TopologicalSort(adjlist adjl) //拓扑排序{stack <int> S;edgenode *p;int i,j,count=0;printf("\n拓扑排序:");for(i=0;i<=adjl.vexnum;i++)if(adjl.adjs[i].id==0)S.push(i);count=0;while(!S.empty()){j=S.top(); S.pop();count++;printf("(%d %c) ",j,adjl.adjs[j].data);for(p=adjl.adjs[i].link;p;p=p->next){int k=p->adjvex;int d=--(adjl.adjs[k].id);if(!d)S.push(k);}}if(count<adjl.vexnum){ printf("\n网中有环!\n");return error;}else return ok;}void prim(graph g){int i,j,k,min;int lowcost[maxlen];int closet[maxlen];printf("最小生成树的边为:\n");for(i=1;i<g.vexnum;i++){lowcost[i]=g.arcs[0][i];closet[i]=1;}closet[1]=0;j=1;for(i=1;i<g.vexnum;i++){min=lowcost[j];k=i;for(j=1;j<g.vexnum;j++)if(lowcost[j]<min&&closet[j]!=0){min=lowcost[j];k=j;}printf("(%c,%c),",g.vexs[k-1],g.vexs[closet[k-1]]);closet[k]=0;for(j=1;j<g.vexnum;j++)if(g.arcs[k][j]<lowcost[j]&&closet[j]!=0){lowcost[j]=g.arcs[k][j];closet[j]=k;}}}int ve[maxlen];int vl[maxlen];status toporder(adjlist adjl,stackstru *t){ //关键路径int i,j,count,k;edgenode *p;initstack(s);initstack(t);for(i=0;i<adjl.vexnum;i++)if(adjl.adjs[i].id==0) push(s,i);count=0;for(i=0;i<adjl.vexnum;i++) ve[i]=0;while(!stackempty(s)){j=pop(s);push(t,j);++count;for(p=adjl.adjs[j].link;p;p=p->next){k=p->adjvex;if(--adjl.adjs[k-1].id==0) push(s,k-1);if(ve[j]+(p->info)>ve[k-1]) ve[k-1]=ve[j]+(p->info);}}if(count<adjl.vexnum) return error;else return ok;}int criticalpath(adjlist adjl){int i,j,k,dut,ee,el;edgenode *p;if(!toporder(adjl,t)) return error;for(i=0;i<adjl.vexnum;i++) vl[i]=ve[i-1];printf("关键路径为:\n");while(!stackempty(t))for(j=pop(t), p=adjl.adjs[j].link;p;p=p->next){k=p->adjvex; dut=(p->info);if(vl[k]-dut<vl[j]) vl[j]=vl[k]-dut;}for(j=0;j<adjl.vexnum;++j)for(p=adjl.adjs[j].link;p;p=p->next){k=p->adjvex;dut=p->info;ee=ve[j];el=vl[k-1]-dut;if(ee==el) printf("(%c,%c)->",adjl.adjs[j].data,adjl.adjs[k-1].data);}return ok;}void shortpath_dijkstra(graph g) //有向网的最短路径{int cost[maxlen][maxlen];int dist[maxlen];int path[maxlen];int s[maxlen];int i,j,v0,min,u;printf("\n请输入起点的编号:");scanf("%d",&v0);v0--;for(i=0;i<g.vexnum;i++){for(j=0;j<g.vexnum;j++)cost[i][j]=g.arcs[i][j];}for(i=0;i<g.vexnum;i++){dist[i]=cost[v0][i];if(dist[i]<large&&dist[i]>0) path[i]=v0;s[i]=0;}s[v0]=1;for(i=0;i<g.vexnum;i++){min=large;u=v0;for(j=0;j<g.vexnum;j++)if(s[j]==0&&dist[j]<min){min=dist[j];u=j;}s[u]=1;for(j=0;j<g.vexnum;j++)if(s[j]==0&&dist[u]+cost[u][j]<dist[j]){dist[j]=dist[u]+cost[u][j];path[j]=u;}}printf("\n顶点%d到各顶点的最短路径长度为:\n",v0);for(i=0;i<g.vexnum;i++)if(s[i]==1){u=i;while(u!=v0){ printf("%4c<-",g.vexs[u]);u=path[u];}printf("%4c",g.vexs[u]);printf(":%d\n",path[i]);}else printf("%4c<-%4c:无路径\n",g.vexs[i],g.vexs[v0]);}void ShowMainMenu(){printf("\n");printf("**************图的基本操作及应用***************\n");printf("* 1 无向图的基本操作及应用*\n");printf("* 2 有向图的基本操作及应用*\n");printf("* 3 无向网的基本操作及应用*\n");printf("* 4 有向网的基本操作及应用*\n");printf("* 5 退出\n");printf("***********************************************\n");}void UDG(){int n;do{printf("\n");printf("**************无向图的基本操作及应用***************\n");printf("* 1 创建无向图的邻接矩阵*\n");printf("* 2 创建无向图的邻接表*\n");printf("* 3 无向图的深度优先遍历*\n");printf("* 4 无向图的广度优先遍历*\n");printf("* 5 退出\n");printf("***************************************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("----------wait-------");creategraph(g);break; //邻接矩阵case 2:printf("----------wait-------");createlist (g,adjl);break; //邻接表case 3:printf("----------wait-------");DFSTraverse(adjl);break; //深度优先搜索case 4:printf("----------wait-------");BFSTraverse(adjl);break; //广度优先搜索case 5:break;default:printf("ERROR!");}}while(n!=5);}void DG(){int n;do{printf("\n");printf("**************有向图的基本操作及应用***************\n");printf("* 1 创建有向图的邻接矩阵*\n");printf("* 2 创建有向图的邻接表*\n");printf("* 3 拓扑排序*\n");printf("* 4 退出*\n");printf("***************************************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("--------wait-------");creategraph(g);break; //邻接矩阵case 2:printf("--------wait-------");createlist (g,adjl);break; //邻接表case 3:printf("--------wait-------");createlist(g,adjl);TopologicalSort(adjl);break; //拓扑排序case 4:break; //退出default:printf("ERROR!");}}while(n!=4);}void UDN(){int n;do{printf("\n");printf("**************无向网的基本操作及应用***************\n");printf("* 1 创建无向网的邻接矩阵*\n");printf("* 2 创建无向网的邻接表*\n");printf("* 3 Prim算法求最小生成树*\n");printf("* 4 kraskal算法求最小生成树*\n");printf("* 5 退出\n");printf("***************************************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("---------wait-------");creategraph(g);break; // 创建无向网的邻接矩阵case 2:printf("--- ----wait-------");createlist (g,adjl);break; // 创建无向网的邻接表case 3:printf("---------wait-------");prim(g);break; //Prim算法求最小生成树case 4:printf("---------wait-------");break;case 5:break;default:printf("ERROR!");}}while(n!=5);}void DN(){int n;do{printf("\n");printf("**************有向网的基本操作及应用***************\n");printf("* 1 创建有向网的邻接矩阵*\n");printf("* 2 创建有向网的邻接表*\n");printf("* 3 关键路径*\n");printf("* 4 单源顶点最短路径问题*\n");printf("* 5 退出\n");printf("***************************************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("---------wait-------");creategraph(g);break; //创建有向网的邻接矩阵case 2:printf("---------wait-------");createlist (g,adjl);break; //创建有向网的邻接表case 3:printf("---------wait-------");criticalpath(adjl);break; //关键路径case 4:printf("---------wait-------");criticalpath(adjl);break; //单源顶点最短路径问题case 5:break; //退出default:printf("ERROR!");}while(n!=5);}void main(){int i,j,k,h,n;do{ShowMainMenu();printf("请选择:");scanf("%d",&n);if(n>5) error;else{g.kind=n;h=n;printf("请输入顶点数,边数:");scanf("%d,%d",&i,&j);g.vexnum=i;adjl.vexnum=i;g.arcnum=j;adjl.arcnum=j;for (i=0;i<g.vexnum;i++){printf("第%d个顶点的信息:",i+1);scanf("%s",&g.vexs[i]);adjl.adjs[i].data=g.vexs[i];adjl.adjs[i].link=null;adjl.adjs[i].id=0;}for (k=1;k<=g.arcnum;k++){//label:if (g.kind==2||g.kind==4)printf("第%d条边的起点编号,终点编号:",k);else printf("第%d条边的两个顶点的编号:",k);scanf("%d,%d",&i,&j);g.a[k-1]=i;g.b[k-1]=j;while (i<1||i>g.vexnum||j<1||j>g.vexnum){printf(" 编号超出范围,重新输入");//goto label;}if (g.kind==3||g.kind==4){printf("\t该边的权值:");scanf("%d",&h);g.h[k-1]=h;}else g.h[k-1]=null;adjl.adjs[i].id++;}switch(n){case 1:UDG();break;case 2:DG();break;case 3:UDN();break;case 4:DN();break;case 5:break;default:printf("ERROR!");break;}}while(n!=5);}三、测试a)程序开始运行,进入选择界面b)选择无向图,并创建无向图C)基于已创建的的无向图选择各项具体的操作四、难点与收获这次的实习报告相对我而言算是比较难的,因为在学这门课程的时候就没怎么专心听讲,所以在拿到计划书的时候,对很多地方感觉很陌生,甚至有一种没办法动手的感觉,加之开始学JAVA以后就很少用C语言编写程序,导致对很多很简单的东西都很陌生,所以熟悉整个C语言的编程环境都花了一段时间。

成人本科函授学位考试课程《数据结构》知识点

成人本科函授学位考试课程《数据结构》知识点

继续教育学院本科学位考试课程《数据结构》知识点一、必须掌握的基本概念(可能的题型为名词解释)算法、数据、数据元素、数据类型、数组、串、模式匹配、顺序表、链表、栈、队列、树、二叉树、满二叉树、完全二叉树、线索二叉树、图、网、有向图、无向图、检索、哈希函数、哈希表、顺序检索、二分法检索、排序、堆二、一般掌握的知识点(可能的题型为填空、单选、多选、判断等客观题)1、算法的5个重要特性。

2、评价算法优劣的5条标准。

3、算法的时间复杂度分析。

4、算法与程序的联系和区别。

5、数据的逻辑结构的基本概念和分类。

什么是线性结构?什么是非线性结构?6、数组的顺序存储结构,数组元素的地址计算。

7、空串与空格串的区别。

8、简单模式匹配算法。

9、线性表的顺序存储和链式存储的特点。

10、栈和队列的特性。

11、循环队列为空的条件和为满的条件。

12、循环链表和双向链表的特点。

13、二叉树的特点和性质。

14、二叉树的存储结构。

15、二叉树的3种遍历(前序、中序、后序)。

16、满二叉树与完全二叉树的异同。

17、完全二叉树的相关计算。

18、计算二叉树的节点数和叶子数。

19、图的存储结构。

20、n个顶点的无向完全图有n(n-1)/2条边,n个顶点的有向完全图有n(n-1)条弧。

有向图中所有结点的入度之和、出度之和均等于边数。

21、有生成树的图是连通图。

对于n个顶点的连通图,其生成树均有n个结点和n-1条边。

22、对有序表进行顺序检索,求其检索成功和不成功的平均检索长度。

23、对有序表进行二分法检索,求其检索成功和不成功的平均检索长度。

24、用线性探查法消除地址冲突构造哈希表。

25、直接插入排序、希尔排序、冒泡排序、快速排序、堆排序、基数排序的时间复杂度、空间复杂度以及稳定性。

三、重点掌握的知识点(可能的题型为简答、论述等主观题)1、线性表的顺序存储和链式存储的具体实现。

2、栈和队列的顺序存储和链式存储的具体实现。

3、已知一棵二叉树的中序遍历和先序(或后序、层序)遍历画出该二叉树。

数据结构名词解释(个人备考时结合群里那个文档和王道书自己摘录的,仅供参考)

数据结构名词解释(个人备考时结合群里那个文档和王道书自己摘录的,仅供参考)

数据结构:一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科。

数据:数据是信息的载体,是描述客观事物属性的数、字符以及所有能输入到计算机中并被计算机程序处理的符号的集合。

数据元素:数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。

数据类型:是一个值的集合和定义在此集合上一组操作的总称。

包括原子类型:其值不可在分的数据类型结构类型:其值可以在分解为若干成分的数据类型抽象数据类型:ADT,指一个数学模型以及定义在该模型上的一组操作。

通常用数据对象、数据关系、基本操作集这样的三元组来表示。

有数据抽象和数据封装两个重要特性。

数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。

包括(逻辑结构、存储结构和数据的运算)。

数据的逻辑结构:指数据元素之间的逻辑关系。

包括集合、线性结构、树形结构、图状结构或网状结构。

数据的存储结构:指数据结构在计算机中的表示,也成物理结构。

主要有顺序存储、连接存储、索引存储、散列存储。

数据的运算:施加在数据上的运算包括运算的定义和实现。

定义是针对逻辑结构,指出运算的功能。

实现是针对存储结构的,指出运算的具体操作步骤。

算法:对特定问题求解步骤的一种描述,是指令的有限序列,其中每一条指令表示一个或多个操作。

有5个重要特性(有穷性、确定性、可行性、输入、输出)算法设计的要求:正确性、可读性、健壮性、效率与低存储量需求。

时间复杂度:一般情况下,算法中基本操作的重复次数是问题规模n的某个函数f(n),算法的时间度量记作T(n)=O(f(n)),表示随着问题规模n的增大,算法执行时间增长率和f(n)的增长率相同,称为时间复杂度。

空间复杂度:S(n)定义为该算法所耗费的村粗空间,是问题规模n的函数。

第二章:线性表线性表:具有相同数据类型的n(n>=0)个数据元素的有限序列。

线性表的顺序存储又称顺序表;链式存储又称单链表。

静态链表:借助数组来描述线性表的链式存储结构,结点也有数据域和指针域。

数据结构设计无向图

数据结构设计无向图

数据结构课程设计——无向图学校专业班级姓名学号任课教师题目3:以邻接链表的方式确定一个无向网,完成:⑴建立并显示出它的邻接矩阵;⑵对该图进行广度优先遍历,显示遍历的结果,(并随时显示队列的入、出情况);⑶普里姆算法构造其最小生成树,随时显示其构造的过程;⑷用克鲁斯卡尔算法构造其最小生成树,随时显示其构造的过程。

一、需求分析1.运行环境:Microsoft Visual Studio 20122.程序所实现的功能:a)建立并显示图的邻接矩阵;b)广度优先遍历该图,显示遍历结果;c)用普里姆算法构造该图的最小生成树,显示构造过程;d)用克鲁斯卡尔算法构造该图的最小生成树,显示构造过程。

3.程序的输入,包含输入的数据格式和说明:a)输入顶点数,及各顶点信息(数据格式为整形);b)输入弧以及其权值(数据格式为整形)。

1.程序的输出,程序输出的形式:a)输出图的邻接矩阵;b)广度优先遍历结果;c)普里姆算法构造最小生成树的结果;d)克鲁斯卡尔算法构造最小生成树的结果。

2.测试数据,如果输入的数据量较大,需要给出测试数据:a)顶点个数:5b)各个顶点为:A B C D Ec)输入所有的弧(格式为“顶点顶点权值”)为:A B 10 A C 4 B D 3 C D 5 B E 6 D E 9二、设计说明算法设计的思想:建立图类,建立相关成员函数。

最后在主函数中实现。

具体成员函数的实现请参看源程序。

在本次的设计中,我采用的是多文件的编程方式。

每个类写成了一个头文件。

这样有助于阅读和查看源程序。

1.邻接链表:邻接链表是一种链式存储结构。

在邻接链表中,对图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点Vi的边(对有向图是以顶点Vi为尾的弧)。

每个结点由3个域组成,其中邻接点域指示与顶点Vi邻接的点在图中的位置,链域指示下一条边或弧的结点;数据域存储和边或弧相关的信息,如权值等。

所以一开始必须先定义邻接链表的边结点类型以及邻接链表类型,并对邻接链表进行初始化,然后根据所输入的相关信息,包括图的顶点数、边数、是否为有向,以及各条边的起点与终点序号,建立图的邻接链表。

有向图及无向图的比较研究

有向图及无向图的比较研究

V2
V3
8
异同点
① 完全有向图有n(n-1)条边。
1
4
证明:若是完全有向图,则n个顶点中
的每个顶点都有一条弧指向其它n-1个 2
3
顶点, 因此总边数=n(n-1)
② 完全无向图有n(n-1)/2 条边。
1
证明:从①可以直接推论出无向完全图的 边数——因为无方向,两弧合并为一边,
2
3
所以边数减半,总边数为n(n-1)/2。
4
精选课件
9
图的邻接表表示
图的邻接表存储方法是一种顺序分配与链式分配相结合 的存储方法,它包括两部分:边表和顶点表。 ➢边表是单链表,用来存放边的信息; ➢顶点表是数组,主要用来存放顶点本身的数据信息和 该顶点邻接点的位置。
边结点
adjvex weight next
顶点结点
v ertex n ex t
m-1
精选课件
11
2 有向图的邻接表和逆邻接表 1)有向图的邻接表 顶点:用一维数组存储(按编号顺序) 以同一顶点为起点的弧:用线性链表存储

下标 编号 link
0 V0 1 V1 2 V2 3 V3
1
2
3 0
类似于无向图的邻接表, 所不同的是:
以同一顶点为起点的弧: 用线性链表存储
V0
V1
m-1

G1=(V1,E1) V1={v0 ,v1,v2,v3,v4} E1={(v0,v1),(v0,v3),(v1,v2),(v1,v4),(v2,v3)(v2,v4)}
无序对(vi,vj): 用连接顶点vi、vj的线段
表示,称为无向边;
精选课件
V0
V1
V2
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<stdio.h>#include<stdlib.h>#define MAX 20#define OK 1#define ERROR 0#define OVERFLOW -2typedef char VertexType;typedef struct ArcNode{int adjvex;int weight;struct ArcNode *nextarc;}ArcNode;typedef struct VNode{int flag;VertexType data;ArcNode *firstarc;}VNode,AdjList[MAX];typedef struct{AdjList vertices;int vexnum,arcnum;}ALGraph;typedef struct{int *front;int *rear;}Queue;bool visit[MAX];int t=0;void CreateGraph(ALGraph &G1,ALGraph &G2); void Create(ALGraph &G1,ALGraph &G2,int a); int LocateVex(ALGraph G,char v);void DFSTraverse(ALGraph G);void DFS(ALGraph &G,int v);void BFSTraverse(ALGraph G);void InitQueue(Queue &Q);void EnQueue(Queue &Q,int v);void DeQueue(Queue &Q,int &u);int QueueEmpty(Queue Q);int FirstAdjVex(ALGraph G,int v);int NextAdjVex(ALGraph G,int v,int w);void Output(ALGraph G1,ALGraph G2,int a);void main(){ALGraph G1,G2;CreateGraph(G1,G2);}void CreateGraph(ALGraph &G1,ALGraph &G2){int i;printf("\n\n\n\n\n\n\t\t\t1 ——无向图");printf("\n\n\n\n\n\n\t\t\t2 ——无向网");printf("\n\n\n\n\n\n\t\t\t3 ——有向图");printf("\n\n\n\n\n\n\t\t\t4 ——有向网");printf("\n\n\n");scanf("%d",&i);switch(i){case 1:system("cls");Create(G1,G2,0);system("cls");Output(G1,G2,0);DFSTraverse(G1);BFSTraverse(G1);break;case 2:system("cls");Create(G1,G2,2);system("cls");Output(G1,G2,2);DFSTraverse(G1);BFSTraverse(G1);break;case 3:system("cls");Create(G1,G2,1);system("cls");Output(G1,G2,1);DFSTraverse(G1);BFSTraverse(G1);DFSTraverse(G2);BFSTraverse(G2);break;case 4:system("cls");Create(G1,G2,3);system("cls");Output(G1,G2,3);DFSTraverse(G1);BFSTraverse(G1);DFSTraverse(G2);BFSTraverse(G2);break;default:system("cls");printf("你的输入有误");}}void Create(ALGraph &G1,ALGraph &G2,int a){int i,j,k,flag1,flag2,b=0;char v1,v2;ArcNode *p1,*p2,*p3,*p4;p1=p2=p3=p4=NULL;printf("请输入顶点数和边数(数字间用空格分隔):");scanf("%d %d",&G1.vexnum,&G1.arcnum);if(a==1||a==3){G2.vexnum=G1.vexnum;G2.arcnum=G1.arcnum;}flushall();printf("\n\n请输入顶点(字符间不要空格):");for(i=0;i<G1.vexnum;i++){scanf("%c",&G1.vertices[i].data);G1.vertices[i].firstarc=NULL;if(a==1||a==3){G2.vertices[i].data=G1.vertices[i].data;G2.vertices[i].firstarc=NULL;}}system("cls");flushall();for(k=0;k<G1.arcnum;k++){if(a==0||a==1){printf("请输入边上的两个顶点(顶点间用空格分隔):");scanf("%c %c",&v1,&v2);}else{printf("请输入边上的两个顶点和权值(顶点和权值间用空格分隔)");scanf("%c %c %d",&v1,&v2,&b);}flushall();printf("\n\n");i=LocateVex(G1,v1);j=LocateVex(G1,v2);p3=(ArcNode *)malloc(sizeof(ArcNode));if(!p3)exit(OVERFLOW);p4=(ArcNode *)malloc(sizeof(ArcNode));if(!p4)exit(OVERFLOW);p3->adjvex=j;p3->weight=b;p3->nextarc=NULL;p4->adjvex=i;p4->weight=b;p4->nextarc=NULL;flag1=flag2=0;if(G1.vertices[i].firstarc){p1=G1.vertices[i].firstarc;flag1=1;while(p1->nextarc)p1=p1->nextarc;}if(a==0||a==2){if(G1.vertices[j].firstarc){p2=G1.vertices[j].firstarc;flag2=1;while(p2->nextarc)p2=p2->nextarc;}}else{if(G2.vertices[j].firstarc){p2=G2.vertices[j].firstarc;flag2=1;while(p2->nextarc)p2=p2->nextarc;}}if(flag1==0)G1.vertices[i].firstarc=p3;elsep1->nextarc=p3;if(a==0||a==2){if(flag2==0)G1.vertices[j].firstarc=p4;elsep2->nextarc=p4;}else{if(flag2==0)G2.vertices[j].firstarc=p4;elsep2->nextarc=p4;}}}int LocateVex(ALGraph G,char v){int i=0;while(G.vertices[i].data!=v)i++;return i;}void DFSTraverse(ALGraph G){int v;static int a=0;if(a==0)printf("邻接表的广度优先搜索结果: ");elseprintf("逆邻接表的广度优先搜索结果: ");for(v=0;v<G.vexnum;v++)G.vertices[v].flag=false;for(v=0;v<G.vexnum;v++){if(!G.vertices[v].flag){DFS(G,v);printf(" ");}}t=0;a=1;printf("\n\n\n\n\n");}void DFS(ALGraph &G,int v){int w;G.vertices[v].flag=true;if(t==1)printf(" -> ");printf("%c",G.vertices[v].data);t=1;for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) {if(!G.vertices[w].flag)DFS(G,w);}}void BFSTraverse(ALGraph G){static int a=0;int v,u,w;Queue Q;for(v=0;v<G.vexnum;v++)G.vertices[v].flag=false;InitQueue(Q);if(a==0)printf("邻接表的广度优先搜索结果: ");elseprintf("逆邻接表的广度优先搜索结果: ");for(v=0;v<G.vexnum;v++){if(!G.vertices[v].flag){G.vertices[v].flag=true;if(t==1)printf(" -> ");t=1;printf("%c",G.vertices[v].data);EnQueue(Q,v);while(!QueueEmpty(Q)){DeQueue(Q,u);for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w)){if(!G.vertices[w].flag){G.vertices[w].flag=true;printf(" -> %c",G.vertices[w].data);EnQueue(Q,w);}}}}printf(" ");}t=0;a=1;printf("\n\n\n\n\n");}void InitQueue(Queue &Q){Q.front=(int *)malloc(MAX*sizeof(int));if(!Q.front)exit(-1);Q.rear=Q.front;}void EnQueue(Queue &Q,int v){*Q.rear++=v;}void DeQueue(Queue &Q,int &u){u=*--Q.rear;}int QueueEmpty(Queue Q){if(Q.front==Q.rear)return OK;elsereturn ERROR;}int FirstAdjVex(ALGraph G,int v){int w;if(G.vertices[v].firstarc){w=G.vertices[v].firstarc->adjvex;return w;}return -1;}int NextAdjVex(ALGraph G,int v,int w){ArcNode *p;p=G.vertices[v].firstarc;while(p->adjvex!=w)p=p->nextarc;if(p->nextarc)return p->nextarc->adjvex;elsereturn -1;}void Output(ALGraph G1,ALGraph G2,int a){int i;ArcNode *p;printf("邻接表的结构:");for(i=0;i<G1.vexnum;i++){printf("\n\t\t\t");printf("%c",G1.vertices[i].data);if(G1.vertices[i].firstarc)p=G1.vertices[i].firstarc;while(p){if(a==2||a==3)printf(" →%d→",p->weight);elseprintf(" →");printf("%d",p->adjvex);p=p->nextarc;}printf("\n\n");}printf("\n\n\n\n\n\n");if(a==1||a==3){printf("逆邻接表的结构:");for(i=0;i<G2.vexnum;i++){printf("\n\t\t\t");printf("%c",G2.vertices[i].data);if(G2.vertices[i].firstarc)p=G2.vertices[i].firstarc;while(p){if(a==3)printf(" →%d→",p->weight);elseprintf(" →");printf("%d",p->adjvex);p=p->nextarc;}printf("\n\n");}printf("\n\n\n");}}。

相关文档
最新文档