图的基本操作与实现Word格式文档下载.docx

上传人:b****3 文档编号:17142758 上传时间:2022-11-28 格式:DOCX 页数:31 大小:96.69KB
下载 相关 举报
图的基本操作与实现Word格式文档下载.docx_第1页
第1页 / 共31页
图的基本操作与实现Word格式文档下载.docx_第2页
第2页 / 共31页
图的基本操作与实现Word格式文档下载.docx_第3页
第3页 / 共31页
图的基本操作与实现Word格式文档下载.docx_第4页
第4页 / 共31页
图的基本操作与实现Word格式文档下载.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

图的基本操作与实现Word格式文档下载.docx

《图的基本操作与实现Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《图的基本操作与实现Word格式文档下载.docx(31页珍藏版)》请在冰豆网上搜索。

图的基本操作与实现Word格式文档下载.docx

对于带权图,结点中还要保存该边的权值cost。

通过在顶点表的第i个顶点信息中保存的指针adj,可以找到与顶点i对应的边链表的第一个边结点;

此外,该记录还保存有该顶点的其他信息。

1.3.2图的深度优先搜索

深度优先搜索是个不断探查和回溯的过程。

在探查的每一步,算法都有一个当前顶点。

最初的当前顶点,也就是指定的起始顶点。

每一步探查过程中,首先对当前顶点v进行访问,并立即设置该顶点的访问标志visited[v]=true。

接着在v的所有邻接顶点中,找出尚未访问过的一个,将其作为下一步探查的当前顶点。

倘若当前顶点的所有邻接顶点都已经被访问过,则退回一步,将前一步所访问的顶点重新取出,当作探查的当前顶点。

重复上述过程,直到最初指定起始顶点的所有邻接顶点都被访问到,此时连通图中的所有顶点也必然都被访问过了。

1.3.3图的广度优先搜索

广度优先搜索时一个逐层遍历的过程,在此过程中,图中有多少顶点就要重复多少步。

每一步都有一个当前顶点。

最初的当前顶点是主过程指定的起始顶点。

在每一步中,首先访问当前顶点v,并设置该顶点的访问标志visited[v]=true。

接着依次访问v的各个未曾被访问过的邻接顶点w1,w2,…,wt,然后再顺序访问w1,w2,…,wt的所有还未被访问过的邻接顶点。

再从这些访问过的顶点出发,再访问它们的所有还未被访问过的邻接顶点,如此做下去,直到图中所有顶点都被访问为止。

2概要设计

2.1程序的整体功能结构

输入1个图先求出每个顶点的度,输出结果;

然后指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列;

接着指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列;

其次输入顶点x,查找图G:

下一步是判断图G是否是连通图,输出信息“YES”/“NO”;

最后如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G的邻接表,即复制图G,然再执行操作

(2);

反之亦然。

2.2数据结构的设计

2.2.1边节点类的定义

structEdge//边结点的定义

{

intdest;

//边的另一顶点位置

Ecost;

//边上的权值

Edge<

T,E>

*link;

//下一条边链指针

};

2.2.2顶点类的定义

template<

classT,classE>

//顶点的定义

structVertex

Tdata;

//顶点的名字

Edge<

*adj;

//边链表的头指针

2.2.3图类的定义

classGraph//图的类定义

{

protected:

intmaxVertices;

//图中最大的顶点数

intnumEdges;

//当前边数

intnumVertices;

//当前顶点数

T*output;

//存放遍历的数组

T*input;

//存放输入数组

Vertex<

*NodeTable;

//顶点表(各边链表的头结点)

intgetVertexPos(constTvertx)//取顶点v在数组中的位置

{

intj=-1;

for(inti=0;

i<

numVertices;

i++)

{

if(NodeTable[i].data==vertx)

j=i;

}

returnj;

}

voidDFS(Graph<

&

G,intv,boolvisited[])//图的深度优先搜索

cout<

<

G.getValue(v)<

'

'

;

//访问顶点v

visited[v]=true;

//作访问标记

intw=G.getFirstNeighbor(v);

//第一个邻接顶点

while(w!

=-1)//若邻接顶点w存在

{

if(!

visited[w])

DFS(G,w,visited);

//若w未访问过,递归访问顶点w

w=G.getNextNeighbor(v,w);

//下一个邻接顶点

public:

Graph();

//构造函数

~Graph();

//析构函数

TgetValue(inti)//取顶点i的值

{

return(i>

=0&

i<

numVertices)?

NodeTable[i].data:

0;

boolinsertVertex(constT&

vertex);

//插入顶点vertex

boolinsertEdge(intv1,intv2,Ecost);

//插入边(v1,v2),权值为cost

boolremoveVertex(intv);

//删除指定的顶点

boolremoveEdge(intv1,intv2);

//删除一条边

intgetFirstNeighbor(intv);

//取顶点v的第一个邻接顶点

intgetNextNeighbor(intv,intw);

//取v的邻接顶点w的下一邻接顶点

intgetFirstCost(intv);

//取顶点v的第一个邻接顶点的cost值

intgetNextCost(intv,intw);

//取v的邻接顶点w的下一邻接顶点的cost值

voidDFS(Graph<

G,constT&

v);

//从顶点v出发对图G进行深度优先遍历的主过程

intBFS(Graph<

T,E>

G,constT&

//图的广度优先搜索

voidWheCan(Graph<

G);

//判断是否为连通图

voidOutPut();

//输出

voidHaveEdge(Graph<

//求顶点的度

voidSerachVertex(Graph<

//输入顶点x,查找图G:

若存在含x的顶点,则删除该结点及与之相关连的边,并作DFS遍历

voidChangeGraph(Graph<

//将用邻接表表示的数转换为邻接矩阵表示

voidInput();

//输入

3详细设计和实现

3.1算法流程图

程序主要设计了六个功能:

首先是求每个顶点的度,然后可以选择对图G作DFS(或BFS)搜索,接着可以判断此图是否连通,接着可以将图G转换为临街矩阵存储方式退出,最后可以对图G作查找顶点。

主函数流程如下:

图3.1.1主函数流程图

3.2各个要求的实现方法

3.2.1自选存储结构,输入含n个顶点(用字符表示顶点)和e条边的图G

采用邻接表的存储结构

N个顶点的输入存储到顶点节点链表(Vertex)中

如果第n个节点和第m个节点之间含有一条边e,就将n和m的顶点链表中指向的边链表中存储入n和m在顶点表中的下标和权值

3.2.2求每个顶点的度,输出结果

顶点的度指与该顶点相关联的边的条数

在用邻接链表做为图的存储方式中,要求一个顶点n的度只要去搜索存放顶点n的边节点链表,其中存放了多少条边的信息,这个顶点的度就为多少。

3.2.3指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列

DFS遍历指的是深度优先搜索

深度优先搜索的基本思想:

DFS在访问图中某一起始顶点v后,由v出发,访问它的任一邻接顶点w1;

再从w1出发,访问与w1邻接但还没有访问过的顶点w2;

然后再从w2出发,进行类似的访问,…如此进行下去,直至到达所有的邻接顶点都被访问过的顶点u为止。

接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。

如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;

如果没有,就再退回一步进行搜索。

重复上述过程,直到连通图中所有顶点都被访问过为止。

3.2.4指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列

BFS指的是广度优先搜索

BFS基本思想:

BFS在访问了起始顶点v之后,由v出发,依次访问v的各个未被访问过的邻接顶点w1,w2,…,wt,然后再顺序访问w1,w2,…,wt的所有还未被访问过的邻接顶点。

再从这些访问过的顶点出发,再访问它们的所有还未被访问过的邻接顶点,…如此做下去,直到图中所有顶点都被访问到为止。

广度优先搜索是一种分层的搜索过程,每向前走一步可能访问一批顶点,不像深度优先搜索那样有往回退的情况。

因此,广度优先搜索不是一个递归的过程。

3.2.5输入顶点x,查找图G:

输入顶点,在顶点表中所搜是否含有这个顶点,如果没有,就输出“无x”。

如果含有,搜索存放顶点n的边节点链表,找出其中存放的顶点m,然后将这个顶点m链表中的存放n的那个节点删除,同时将n中存放m的节点删除。

然后在顶点链表中存放顶点n的节点删除。

3.2.6判断图G是否是连通图,输出信息“YES”/“NO”;

对图做BFS遍历,如果遍历到的顶点数等于当前的顶点数的个数,这个图就是联通图,反之就不是连通图

3.2.7如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G的邻接表,即复制图G,然再执行操作

(2);

反之亦然

我采用的是邻接矩阵做为图的存储结构。

将用邻接表存储的图转化为邻接矩阵的存储的基本思想是:

(1)将图的顶点表中存放的顶点的信息都存放在一个顶点矩阵中

(2)逐个搜索各个顶点的边节点链表,如果含有节点,将邻接矩阵中对应二维数组的值赋值为cost的值。

顶点的度为:

统计第i行(列)不为0的个数可得顶点i的度。

3.3主程序设计

///////////////////////////////////////////////////Graph.h

#include<

iostream>

stdlib.h>

#include"

Queue.h"

usingnamespacestd;

intdest;

Ecost;

Edge(){}//构造函数

Edge(intnum,Ecost):

dest(num),weight(cost),link(NULL){}//构造函数

booloperator!

=(Edge<

R)const//判边等否

{

returndest!

=R.dest;

Tdata;

Edge<

Graph<

:

Graph()//构造函数:

建立一个空的邻接表

{

maxVertices=100;

numVertices=0;

numEdges=0;

NodeTable=newVertex<

[maxVertices];

//创建顶点表数组

if(NodeTable==NULL)

cerr<

"

存储分配错!

endl;

exit

(1);

for(inti=0;

maxVertices;

i++)

NodeTable[i].adj=NULL;

output=newT[maxVertices];

}

~Graph()//析构函数:

删除一个邻接表

*p=NodeTable[i].adj;

while(p!

=NULL)

{

NodeTable[i].adj=p->

link;

deletep;

p=NodeTable[i].adj;

}

delete[]NodeTable;

//删除顶点表数组

boolGraph<

insertVertex(constT&

vertex)//插入顶点

if(numVertices==maxVertices)

returnfalse;

NodeTable[numVertices].data=vertex;

numVertices++;

returntrue;

template<

classT,classE>

insertEdge(intv1,intv2,Ecost)//插入边(v1,v2),权值为cost

if(v1>

=0&

v1<

=numVertices&

v2>

v2<

=numVertices)

*q,*p=NodeTable[v1].adj;

//v1对应的边链表头z指针

while(p!

=NULL&

p->

dest!

=v2)//寻找邻接顶点v2

p=p->

if(p!

=NULL)//找到此边不插入

returnfalse;

p=newEdge<

//否则创建新节点

q=newEdge<

p->

dest=v2;

cost=cost;

link=NodeTable[v1].adj;

//链入v1的边链表

NodeTable[v1].adj=p;

q->

dest=v1;

link=NodeTable[v2].adj;

//链入v2的边链表

NodeTable[v2].adj=q;

numEdges++;

returntrue;

else

参数有误!

请重新输入!

removeVertex(intv)

if(numVertices==1||v<

0||v>

参数有误,请重新输入!

//表空或顶点超出范围

*p,*s,*t;

intk;

while(NodeTable[v].adj!

=NULL)

p=NodeTable[v].adj;

k=p->

dest;

s=NodeTable[k].adj;

t=NULL;

while(s!

s->

=v)

t=s;

s=s->

if(s!

if(t==NULL)

NodeTable[k].adj=s->

else

t->

link=s->

deletes;

NodeTable[v].adj=p->

deletep;

numEdges--;

numVertices--;

NodeTable[v].data=NodeTable[numVertices].data;

p=NodeTable[v].adj=NodeTable[numVertices].adj;

while(p!

s=NodeTable[p->

dest].adj;

if(s->

dest==numVertices)

{

s->

dest=v;

break;

}

s=s->

removeEdge(intv1,intv2)

if(v1!

=-1&

v2!

=-1)

*p=NodeTable[v1].adj,*q=NULL,*s=p;

des

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 职业规划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1