当前位置:文档之家› 图的基本操作与实现的课程设计报告

图的基本操作与实现的课程设计报告

图的基本操作与实现的课程设计报告中国矿业大学徐海学院计算机系《软件认知实践》报告姓名:_学号:专业:___________________设计题目:_______________指导教师:____________________________2013年12月30日第1章题目概述 第1.1节题目要求. 第1.2节主要难点 第2章系统流程 第3章数据结构和算法 第4章核心代码分析.. 第5章复杂度分析 参考文献第一章题目概述第1.1节题目要求 (1) 自选存储结构,输入含n 个顶点(用字符表示顶点)和e 条边的图G ;(2) 求每个顶点的度,输出结果;(3) 指定任意顶点x 为初始顶点,对图G 作DFS 遍历,输出DFS 顶点序列(提示:使用一个栈实 现 DFS);⑷指定任意顶点x 为初始顶点,对图G 作BFS 遍历,输出BFS 顶点序列(提示:使用一个队列 实现BFS);(5) 输入顶点x,查找图G:若存在含x 的顶点,则删除该结点及与之相关连的边,并作DFS 遍历(执行操作3);否则输出信息“无x” ;(6) 判断图G 是否是连通图,输出信息“YES” / “NO”;(7) 如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G 的邻接表,即复制图G,然再执行操作(2);反之亦然。

.2 .2 .3 .4 .5.62525第1. 2节主要难点(1)自选存储结构创建一个图:通过用户从键盘敲入的两个数值分别确定图的顶点数和边数,选择邻接矩阵存储结构将图的结点信息存储在一个顺序表中,图的边信息存储在一个二维数组中。

(2)求每个顶点的度:1.邻接矩阵存储结构下求每个顶点的度:利用图的邻接矩阵,每个顶点所在行和所在列的边的权值如果存在则该顶点的度+1,依次算出每个顶点的度,并且记录在一个数组中输出。

2.邻接表存储结构下求每个顶点的度:定义一个邻接边指针循环指向顶点的邻接边单链表头结点,当结点不空时,该顶点的出度+1,邻接边弧头结点的入度+1,依次求出每个顶点的出度和入度之和就为该顶点的度。

(3)图的深度优先遍历:采取邻接矩阵结构,指定任意顶点x为初始顶点1.访问结点V并标记结点V己访问;2.查找结点v的第一个邻接结点w;3.若结点v的邻接结点w存在,则继续执行,否则算法结束;4.若结点w尚未被访问,则递归访问结点w;5.查找结点v的w邻接结点的下一个邻接结点w,转到步骤3o(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 o(5)判断有向图的强连通性:采取邻接表结构,在图中寻找一个包含所有顶点且首尾相连的环,若这样的环存在,则该图为强连通图,否则不为强连通图。

(6)用邻接矩阵的信息生成邻接表:定义一个邻接表的边信息结构体,将邻接矩阵的边信息转换成邻接表的边信息存储到邻接边的单链表中。

第二章系统流程图第三章数据结构和算法(1)有向图顶点的数据类型DataType定义如下:typedef int DataType ;(2)邻接矩阵存储结构下图的结构体定义如下:typedef struct{SeqList Vertices;int edge[MaxVertices][MaxVertices];int numOfEdges;}AdjMGraph;(3)邻接矩阵存储结构下图的边信息结构体定义如下:typedef struct{int row;int col;int weight;}RowColWeight;(4)邻接表存储结构下图的结构体定义如下:typedef struct Node{int dest;struct Node *next;}Edge;typedef struct{DataType data;int sorce;Edge *adj;}AdjLHeight;typedef struct{AdjLHeight a[MaxVertices];int numOfVerts;int numOfEdges;}AdjLGraph;(5)邻接表存储结构下图的边信息结构体定义如下:typedef struct{int row;int col;}RowCol;(6)顺序循环队列的结构体定义如下:typedef struct{DataType queue[MaxQueueSize];int rear;int front;int count;}SeqCQueue;(7)顺序表的结构体定义如下:typedef struct{DataType list [MaxSize];int size;JSeqList;第四章核心代码分析源程序存放在八个文件夹中,文件SeqList.h是顺序表的结构体定义和操作函数,文件SeqCQueue. h是顺序循环队列的结构体定义和操作函数,文件AdjMGraph. h是邻接矩阵存储结构下图的结构体定义和操作函数,文件AdjMGraphCreate. h是邻接矩阵存储结构下图的创建函数, 文件AdjLGraph. h是邻接表存储结构下图的结构体定义和操作函数,文件AdjLGraphCreate. h 是邻接表存储结构下图的创建函数,文件AdjMGraphTraverse. h是邻接矩阵存储结构下图的深度优先遍历和广度优先遍历操作函数,文件图的基本操作与实现.c是主函数。

(1)/* 文件 SeqList. h */typedef structDataType list [MaxSize]: int size;JSeqList;void Listinitiate(SeqList *L)L->size=0;}int ListLength(SeqList L){return L. size;)int Listinsert (SeqList *L, int i, DataType x){int j;if(L->size>=MaxSize){printfC数组已满无法插入!\n");return 0;)else if(i<0||i>L->size)(printf (”参数不合法! \n");return 0;)else(for (j=L->size;j>i;i—)L->list[j]=L->list[j-1];L->list[i]=x;L->size++;retxirn 1;)}int ListDelete(SeqList *L)int i, DataType *x){int j;if(L->size<=0)(printf r顺序表己空无数据元素可删!\n");return 0;)else if(i<0||i>L->size-l)printf ("参数i不合法! \rT);return 0;}else{*x=L->list[i];for(j=i+l;j<=L->size~l;j++)L->list[j-l]=L->list[j];L->size—;return 1;)}int ListGet(SeqList L, int i, DataType *x){if (i<0||i>L. size-1){printfC参数i不合法!\n");return 0;)else(*x=L. list[i];return 1;}}(2)/* 文件 SeqCQueue. h */typedef struct{DataType queue[MaxQueueSize];int rear;int front;int count;}SeqCQueue;void Queueinitiate(SeqCQueue *Q){Q->rear=0;Q-〉front =0;Q->count =0;}int QueueNotEmpty(SeqCQueue Q){if(Q. count 1=0) return 1;else return 0;}int QueueAppend(SeqCQueue *Q, DataType x){if(Q->count>0&&Q->rear==Q->front){printfC队列已满无法插入!”);return 0;)else(Q->queue [Q->rear]=x;Q->rear =(Q->rear +1)%MaxQueueSize;Q->count ++;return 1;})int QueueDelete(SeqCQueue *Q, DataType *d){if(Q->count ==0)(printfC队列己空无数据出队列! \n"); return 0;)else(*d=Q->queue[Q->front];Q->front=(Q->front+l)%MaxQueueSize;Q->count —;return 1;})int QueueGet(SeqCQueue Q, DataType*d){if (Q. count ==0){printfC队列已空无数据出队列! \n");return 0;}else*d=Q. queue [Q. front ]; return 1;}(3)/* 文件 AdjMGraph. h*/#include*SeqList. h” typedef struct {SeqList Vertices; 〃存放结点的顺序表int edge [MaxVertices] [MaxVertices]; 〃存放边的邻接矩阵int numOfEdges;〃边的条数} AdjMGraph; 〃边的结构体定义void Initiate (AdjMGraph *G, int n) //初始化{ int i, j;for(i=0;i<n;i++)for(j=0;j<n;j++)(if(i=j)G->edge[i][j]=0; elseG->edge[i] [j]=MaxWeight;}G->numOfEdges=O; 〃边的条数置为0Listinitiate (&G->Vertices); //顺序表初始化}void InsertVertex(AdjMGraph *G, DataType vertex) 〃在图G 中插入结点vertex { Listinsert (&G->Vertices, G->Vertices. size, vertex); 〃顺序表尾插入}void InsertEdge(AdjMGraph *G, int vl, int v2, int weight)//在图G中插入边v2>,边<vl, v2>的权为weight {if(vl<01|vl>G->Vertices. size v2<01|v2>G->Vertices. size)printf ('参数vl或v2越界出错! \n"); exit (1);}G->edge[vl][v2]=weight;G->numOfEdges++;}void De let eEdge (AdjMGraph *G, int vl, int v2) //在图中删除边<vl, v2> {if(vl<01|vl>G->Vertices. size v2<01|v2>G->Vertices. size| i vl==v2) {printf (*参数vl或v2越界出借! \n");exit(l);)if(G->edge[vl][v2]==MaxWeight||vl==v2){printf C该边不存在! \n");exit (0);)G->edge[vl][v2]=MaxWeight;G->numOfEdges一;}void DeleteVerten(AdjMGraph *G, int v) //删除结点v{int n=ListLength(G->Vertices), i> j;DataType x;for(i=0;i<n;i++) 〃计算删除后的边数(for (j=0;j<n;j++)if ((i=v| | j=v)&&G->edge[i] [j]>O&&G->edge[i] [j]<MzixWeight) G->num0f Edges—; //计算被删除边}for(i=v;i<n;i++) //删除第v 行(for(j=0;j<n;j++)G->edge[i][j]=G->edge[i+l] [j];)for(i=0;i<n;i++) 〃删除第v 列(for(j=v;j<n;j++)G->edge[i][j]=G->edge[i][j+1];)ListDelete (&G->Vertices, v, &x); //删除结点v }int GetFistVex (AdjMGraph *G, int v)//在图G中寻找序号为v的结点的第一个邻接结点〃如果这样的邻接结点存在,返回该邻接结点的序号;否则,返回-1{int col;if(v<0|Iv>G->Vertices. size){printfC参数vl越界出错!\n。

相关主题