图的基本操作与实现的课程设计报告Word文件下载.docx
《图的基本操作与实现的课程设计报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《图的基本操作与实现的课程设计报告Word文件下载.docx(30页珍藏版)》请在冰豆网上搜索。
4.若结点w尚未被访问,则递归访问结点w;
5.查找结点v的w邻接结点的下一个邻接结点w,转到步骤3。
(4)图的广度优先遍历:
采取邻接矩阵结构,指定任意顶点x为初始顶点,利用顺序循环队列以保持访问过的结点的顺序
1.首先访问初始结点v并标记结点v为已访问;
2.结点v入队列;
3.当队列非空时则继续执行,否则算法结束;
4.出队列取得队头结点u;
5.查找u的第一个邻接结点w;
6.若u的邻接结点w不存在则转到步骤3,否则循环执行下列步骤:
6.1若结点w尚未被访问,则访问结点w并标记结点w为已访问;
6.2结点w入队列;
6.3查找结点u的w邻接结点的下一个邻接结点w,转到步骤6。
(5)判断有向图的强连通性:
采取邻接表结构,在图中寻找一个包含所有顶点且首尾相连的环,若这样的环存在,则该图为强连通图,否则不为强连通图。
(6)用邻接矩阵的信息生成邻接表:
定义一个邻接表的边信息结构体,将邻接矩阵的边信息转换成邻接表的边信息存储到邻接边的单链表中。
第二章系统流程图
第3章数据结构和算法
(1)有向图顶点的数据类型DataType定义如下:
typedefintDataType;
(2)邻接矩阵存储结构下图的结构体定义如下:
typedefstruct
{
SeqListVertices;
intedge[MaxVertices][MaxVertices];
intnumOfEdges;
}AdjMGraph;
(3)邻接矩阵存储结构下图的边信息结构体定义如下:
introw;
intcol;
intweight;
}RowColWeight;
(4)邻接表存储结构下图的结构体定义如下:
typedefstructNode
intdest;
structNode*next;
}Edge;
DataTypedata;
intsorce;
Edge*adj;
}AdjLHeight;
AdjLHeighta[MaxVertices];
intnumOfVerts;
}AdjLGraph;
(5)邻接表存储结构下图的边信息结构体定义如下:
}RowCol;
(6)顺序循环队列的结构体定义如下:
typedefstruct
DataTypequeue[MaxQueueSize];
intrear;
intfront;
intcount;
}SeqCQueue;
(7)顺序表的结构体定义如下:
DataTypelist[MaxSize];
intsize;
}SeqList;
第四章核心代码分析
源程序存放在八个文件夹中,文件SeqList.h是顺序表的结构体定义和操作函数,文件SeqCQueue.h是顺序循环队列的结构体定义和操作函数,文件AdjMGraph.h是邻接矩阵存储结构下图的结构体定义和操作函数,文件AdjMGraphCreate.h是邻接矩阵存储结构下图的创建函数,文件AdjLGraph.h是邻接表存储结构下图的结构体定义和操作函数,文件AdjLGraphCreate.h是邻接表存储结构下图的创建函数,文件AdjMGraphTraverse.h是邻接矩阵存储结构下图的深度优先遍历和广度优先遍历操作函数,文件图的基本操作与实现.c是主函数。
(1)/*文件SeqList.h*/
DataTypelist[MaxSize];
intsize;
}SeqList;
voidListInitiate(SeqList*L)
L->
size=0;
}
intListLength(SeqListL)
returnL.size;
intListInsert(SeqList*L,inti,DataTypex)
intj;
if(L->
size>
=MaxSize)
{
printf("
数组已满无法插入!
\n"
);
return0;
}
elseif(i<
0||i>
L->
size)
参数不合法!
else
for(j=L->
size;
j>
i;
i--)L->
list[j]=L->
list[j-1];
L->
list[i]=x;
size++;
return1;
intListDelete(SeqList*L,inti,DataType*x)
size<
=0)
顺序表已空无数据元素可删!
return0;
size-1)
参数i不合法!
*x=L->
list[i];
for(j=i+1;
j<
=L->
size-1;
j++)L->
list[j-1]=L->
list[j];
size--;
intListGet(SeqListL,inti,DataType*x)
if(i<
L.size-1)
*x=L.list[i];
(2)/*文件SeqCQueue.h*/
DataTypequeue[MaxQueueSize];
intrear;
intfront;
intcount;
}SeqCQueue;
voidQueueInitiate(SeqCQueue*Q)
Q->
rear=0;
front=0;
count=0;
intQueueNotEmpty(SeqCQueueQ)
if(Q.count!
=0)return1;
elsereturn0;
intQueueAppend(SeqCQueue*Q,DataTypex)
if(Q->
count>
0&
&
Q->
rear==Q->
front)
队列已满无法插入!
"
else
Q->
queue[Q->
rear]=x;
rear=(Q->
rear+1)%MaxQueueSize;
count++;
intQueueDelete(SeqCQueue*Q,DataType*d)
count==0)
队列已空无数据出队列!
*d=Q->
queue[Q->
front];
front=(Q->
front+1)%MaxQueueSize;
count--;
intQueueGet(SeqCQueueQ,DataType*d)
if(Q.count==0)
*d=Q.queue[Q.front];
(3)/*文件AdjMGraph.h*/
#include"
SeqList.h"
SeqListVertices;
//存放结点的顺序表
intedge[MaxVertices][MaxVertices];
//存放边的邻接矩阵
intnumOfEdges;
//边的条数
}AdjMGraph;
//边的结构体定义
voidInitiate(AdjMGraph*G,intn)//初始化
inti,j;
for(i=0;
i<
n;
i++)
for(j=0;
j++)
{
if(i==j)
G->
edge[i][j]=0;
else
edge[i][j]=MaxWeight;
}
G->
numOfEdges=0;
//边的条数置为0
ListInitiate(&
G->
Vertices);
//顺序表初始化
voidInsertVertex(AdjMGraph*G,DataTypevertex)//在图G中插入结点vertex
ListInsert(&
Vertices,G->
Vertices.size,vertex);
//顺序表尾插入
voidInsertEdge(AdjMGraph*G,intv1,intv2,intweight)
//在图G中插入边<
v1,v2>
边<
的权为weight
if(v1<
0||v1>
Vertices.size||v2<
0||v2>
Vertices.size)
参数v1或v2越界出错!
exit
(1);
G->
edge[v1][v2]=weight;
numOfEdges++;
voidDeleteEdge(AdjMGraph*G,intv1,intv2)//在图中删除边<
Vertices.size||v1==v2)
if(G->
edge[v1][v2]==MaxWeight||v1==v2)
该边不存在!
exit(0);
edge[v1][v2]=MaxWeight;
numOfEdges--;
voidDeleteVerten(AdjMGraph*G,intv)//删除结点v
intn=ListLength(G->
Vertices),i,j;
DataTypex;
i++)//计算删除后的边数
if((i==v||j==v)&
edge[i][j]>
edge[i][j]<
MaxWeight)
//计算被删除边
for(i=v;
i++)//删除第v行
G->
edge[i][j]=G->
edge[i+1][j];
i++)//删除第v列
for(j=v;
edge[i][j+1];
ListDelete(&
Vertices,v,&
x);
//删除结点v
intGetFistVex(AdjMGraph*G,intv)
//在图G中寻找序号为v的结点的第一个邻接结点
//如果这样的邻接结点存在,返回该邻接结点的序号;
否则,返回-1
intcol;
if(v<
0||v>
参数v1越界出错!
for(col=0;
col<
Vertices.size;
col++)
if(G->
edge[v][col]>
edge[v][col]<
MaxWeight)returncol;
return-1;
intGetNextVex(AdjMGraph*G,intv1,intv2)
//在图中寻找v1结点的邻接结点v2的下一个邻接结点
//如果这样的结点存在,返回该邻接结点的序号;
//v1和v2都是相应结点的序号
for(col=v2+1;
if(G->
edge[v1][col]>
edge[v1][col]<
//输出图G的邻接矩阵
voidPrint(AdjMGraph*G)
printf("
%6d"
G->
edge[i][j]);
//邻接矩阵存储结构下求出每个顶点的度并输出
voidMVertices(AdjMGraph*G,DataTypea[])
inti,j,m;
DataTypeb[MaxVertices];
//用数组b[]记录相应结点的度
b[i]=0;
//置0
printf("
邻接矩阵存储结构下图的顶点的度为:
for(m=0;
m<
m++)//求出每个结点的度
for(i=0;
for(j=0;
{
if(i==m&
//求出邻接矩阵第i行权值存在的边的个数,当边<
m,j>
存在时,b[m]加1
b[m]++;
if(j==m&
i!
=m&
//求出邻接矩阵第j列权值存在的边的个数,当边<
i,m>
存在时,b[m]加1
}
顶点%d的度为:
%d\n"
a[m],b[m]);
//查找图G中是否存在点v
intChaZhao(AdjMGraph*G,intv)
if(0<
=v&
v<
存在顶点%d\n"
v);
不存在顶点%d\n"
//删除查找到的结点v并删除该结点及与之相关的边
voidMDelete(AdjMGraph*G,intv)
inti;
edge[v][i]>
edge[v][i]<
//当邻接矩阵的第v行有边<
v,i>
存在时,删除边<
DeleteEdge(G,v,i);
edge[i][v]>
edge[i][v]<
//当邻接矩阵的第j行有边<
i,v>
DeleteEdge(G,i,v);
DeleteVerten(G,v);
//删除结点v
(4)/*文件AdjMGraphCreate.h*/
introw;
//行下标
//列下标
intweight;
//权值
}RowColWeight;
//边信息结构体定义
voidCreatGraph(AdjMGraph*G,DataTypev[],intn,RowColWeightE[],inte)
//在图G中插入n个结点信息v和e条边信息E
inti,k;
Initiate(G,n);
//结点顺序表初始化
InsertVertex(G,v[i]);
//结点插入
for(k=0;
k<
e;
k++)
InsertEdge(G,E[k].row,E[k].col,E[k].weight);
//边插入
(5)/*文件AdjLGraph.h*/
//邻接表的存储结构
intdest;
//邻接边的弧头结点序号
structNode*next;
}Edge;
//邻接边单链表的结点结构体
DataTypedata;
//结点数据元素
intsorce;
//邻接边的弧尾结点序号
Edge*adj;
//邻接边的头指针
}AdjLHeight;
//数组的数据元素类型结构体
AdjLHeighta[MaxVertices];
//邻接表数组
intnumOfVerts;
//结点个数
//边个数
}AdjLGraph;
//邻接表结构体
//初始化操作函数
voidLAdjInitiate(AdjLGraph*G)
numOfVerts=0;
MaxVertices;
a[i].sorce=i;
a[i].adj=NULL;
//撤销操作函数
voidLAdjDestroy(AdjLGraph*G)
//撤销图G中的所有邻接边单链表
Edge*p,*q;
numOfVerts;
p=G->
a[i].adj;
while(p!
=NULL)
q=p->
next;
free(p);
p=q;
//插入结点操作函数
voidLInsertVertex(AdjLGraph*G,inti,DataTypevertex)
//在图G中的第i(0<
=i<
MaxVertices)个位置插入结点数据元素vertex
if(i>
=0&
MaxVertices)
a[i].data=vertex;
//存储结点数据元素vertex
numOfVerts++;
//个数加1
结点越界"
//插入边操作函数
voidLInsertEdge(AdjLGraph*G,intv1,intv2)
//在图G中加入边<
的信息
Edge*p;
//定义一个邻接边指针
=G->
numOfVerts||v2<
numOfVerts)
参数v1或v2越界出错"
p=(Edge*)malloc(sizeof(Edge));
//申请邻接边单链表结点空间
p->
dest=v2;
//置邻接边弧头序号
next=G->
a[v1].adj;
//新结点插入单链表的表头
a[v1].adj=p;
//头指针指向新的单链表表头
//边数个数加1
}
//删除边操作函数
voidLDeleteEdge(AdjLGraph*G,intv1,intv2)
//删除图G中的边