数据结构实验七图的创建与遍历
数据结构中图的建立与深度优先、广度优先遍历
数据结构中图的建立与深度优先、广度优先遍历《数据结构》实验报告实验内容:图的建立(邻接矩阵)及其深度优先、广度优先遍历学号:姓名:一、上机实验的问题和要求(需求分析):[ 题目]二、程序设计的基本思想,原理和算法描述:设计一个程序,建立图的邻接矩阵,并且进行图的广度优先遍历。
三、调试和运行程序过程中产生的问题及采取的措施:(略)四、源程序及注释[ 源程序] 程序名:9.cpp#include"stdio.h"#include"stdlib.h"#define INFINITY 100#define MAX_VERTEX_NUM 20#define MAX 100#define OK 1#define ERROR 0#define NULL 0typedef int VRType;typedef int VertextType;typedef int Status;typedef enum {DG,DN,UDG,UDN}GraphKind;typedef struct ArcCell{VRType adj;}ArcCell,AdjMatrix[MAX_VERTEX_NUM ][MAX_VERTEX_NUM ]; typedef struct{int vexs[MAX_VERTEX_NUM ];int arcs[4][4] ;int vexnum,arcnum;GraphKind Kind;}MGraph;int LocateVex(MGraph G,int v1){ int i;for(i=0;i<g.vexnum;i++)< p="">if(G.vexs[i]==v1)printf("%d\n",i);return i;}Status CreateUDN(MGraph &G){ int v1,v2;int i,j,k,w;printf("输入图的顶点数和弧数:");scanf("%d,%d",&G.vexnum,&G.arcnum); printf("输入顶点:");for(i=0;i<g.vexnum;i++)< p="">scanf("%d",&G.vexs[i]);for(i=0;i<g.vexnum;i++)< p="">for(j=0;j<g.vexnum;j++)< p="">G.arcs[i][j]=INFINITY ;printf("输入顶点关系:");for(k=0;k<g.arcnum;k++)< p="">{scanf("%d%d%d",&v1,&v2,&w);i=LocateVex(G,v1);j=LocateVex(G,v2);G.arcs[i][j]=w;G.arcs[j][i]=G.arcs[i][j];printf("%d\n%d\n",G.arcs[i][j],G.arcs[j][i]);}printf("图的邻接矩阵图是:\n");for(i=0;i<g.vexnum;i++)< p="">{for(j=0;j<g.vexnum;j++)< p="">printf("%d",G.arcs[i][j]);printf("\n");}return OK;}Status Visit(int e){//输出函数printf("%d\n",e);return OK;}//PrintElement//Status(*VisitFunc)(char v);int visited[MAX];void DFS(MGraph G,int v){ int j;Visit (v);visited[v]=1;for(j=1;j<g.vexnum;j++)< p="">if(!visited[j]&&G.arcs[v][j]!=INFINITY)DFS(G,j); } void DFSTraverse(MGraph G){ int v;for(v=0;v<g.vexnum;++v)< p="">visited[v]=0;for(v=0;v<g.vexnum;++v)< p="">if(!visited[v])DFS(G,v);/* 有关队列的操作*/#define MAX SIZE 100#define QElemType int#define OVERFLOW 0typedef struct{QElemType *base;int front;int rear;}SqQueue;Status InitQueue(SqQueue &Q){ Q.base=(QElemType*)malloc(MAXSIZE* sizeof(QElemType)); if(!Q.base)exit(OVERFLOW);Q.front=Q.rear=0;return 0;}Status EnQueue(SqQueue &Q,QElemType e){if(Q.rear+1==Q.front)return ERROR;Q.base[Q.rear]=e;Q.rear=Q.rear+1;return OK;}Status DeQueue(SqQueue &Q,QElemType &e){if(Q.front==Q.rear)return ERROR;e=Q.base[Q.front];Q.front=Q.front+1;return OK;}Status QueueEmpty(SqQueue Q){if(Q.front==Q.rear)return OK;else return ERROR;void BFSTraverse(MGraph &G){ int v,u,j;SqQueue Q;for(v=0;v<g.vexnum;v++)< p=""> visited[v]=0;InitQueue(Q);for(v=0;v<g.vexnum;++v)< p="">if(!visited[v]){visited[v]=1;Visit(v);EnQueue(Q,v);while(!QueueEmpty(Q)){ DeQueue(Q,u);for(j=1;j<g.vexnum;j++)< p="">if(!visited[j]&&G.arcs[v][j]!=INFINITY) { visited[j]=1;Visit(j);EnQueue(Q,j);}} }}void main(){ MGraph G;CreateUDN(G);printf("建图成功!");printf("深度优先遍历的结果:\n"); DFSTraverse(G);printf("广度优先遍历的结果:\n"); BFSTraverse(G);}五、运行结果运行结果:上一页下一页</g.vexnum;j++)<></g.vexnum;++v)<></g.vexnum;v++)<></g.vexnum;++v)<> </g.vexnum;++v)<> </g.vexnum;j++)<> </g.vexnum;j++)<> </g.vexnum;i++)<> </g.arcnum;k++)<> </g.vexnum;j++)<> </g.vexnum;i++)<> </g.vexnum;i++)<> </g.vexnum;i++)<>。
数据结构课程设计-图的遍历和构建
摘要图(Graph)是一种复杂的非线性结构。
图可以分为无向图、有向图。
若将图的每条边都赋上一个权,则称这种带权图网络。
在人工智能、工程、数学、物理、化学、计算机科学等领域中,图结构有着广泛的应用。
在图结构中,对结点(图中常称为顶点)的前趋和后继个数都是不加以限制的,即结点之间的关系是任意的。
图中任意两个结点之间都可能相关。
图有两种常用的存储表示方法:邻接矩阵表示法和邻接表表示法。
在一个图中,邻接矩阵表示是唯一的,但邻接表表示不唯一。
在表示的过程中还可以实现图的遍历(深度优先遍历和广度优先遍历)及求图中顶点的度。
当然对于图的广度优先遍历还利用了队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)来实现。
这不仅让我们巩固了之前学的队列的基本操作,还懂得了将算法相互融合和运用。
目录第一章课程设计目的..................................................................................... 错误!未定义书签。
第二章课程设计内容和要求....................................................................... 错误!未定义书签。
2.1课程设计内容.................................................................................. 错误!未定义书签。
2.1.1图的邻接矩阵的建立与输出ﻩ错误!未定义书签。
2.1.2图的邻接表的建立与输出............................................... 错误!未定义书签。
2.1.3图的遍历的实现.................................................................... 错误!未定义书签。
数据结构C语言版——图的建立与遍历
typedef struct VNode{
VertexType data;
ArcNode *firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum,arcnum;
int kind;
typedef int Status;
//图的邻接矩阵——数组存储表示-------------------------
#define INF0
typedef int VRType;
typedef char VertexType[20];
{
scanf("%s%s",v1,v2);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G->arcs[i][j].adj=1;
G->arcs[j][i]=G->arcs[i][j];
}
return(1);
}
int LocateVex(MGraph *G,VertexType v){
Boolean visited[MAX_VERTEX_NUM];
void Dfs(MGraph *G,int v)
{
int w;
visited[v]=TRUE;
printf("%s",G->vexs[v]);
for(w=FirstAdjVex(G,v); w>=0;w=NextAdjVex(G,v,w))
AdjMatrix arcs;
int vexnum,arcnum;
}MGraph;
数据结构实验报告-图的遍历
数据结构实验报告实验:图的遍历一、实验目的:1、理解并掌握图的逻辑结构和物理结构——邻接矩阵、邻接表2、掌握图的构造方法3、掌握图的邻接矩阵、邻接表存储方式下基本操作的实现算法4、掌握图的深度优先遍历和广度优先原理二、实验内容:1、输入顶点数、边数、每个顶点的值以及每一条边的信息,构造一个无向图G,并用邻接矩阵存储改图。
2、输入顶点数、边数、每个顶点的值以及每一条边的信息,构造一个无向图G,并用邻接表存储该图3、深度优先遍历第一步中构造的图G,输出得到的节点序列4、广度优先遍历第一部中构造的图G,输出得到的节点序列三、实验要求:1、无向图中的相关信息要从终端以正确的方式输入;2、具体的输入和输出格式不限;3、算法要具有较好的健壮性,对错误操作要做适当处理;4、程序算法作简短的文字注释。
四、程序实现及结果:1、邻接矩阵:#include <stdio.h>#include <malloc.h>#define VERTEX_MAX 30#define MAXSIZE 20typedef struct{intarcs[VERTEX_MAX][VERTEX_MAX] ;int vexnum,arcnum;} MGraph; void creat_MGraph1(MGraph *g) { int i,j,k;int n,m;printf("请输入顶点数和边数:");scanf("%d%d",&n,&m);g->vexnum=n;g->arcnum=m;for (i=0;i<n;i++)for (j=0;j<n;j++)g->arcs[i][j]=0;while(1){printf("请输入一条边的两个顶点:\n");scanf("%d%d",&i,&j);if(i==-1 || j==-1)break;else if(i==j || i>=n || j>=n){printf("输入错误,请重新输入!\n");}else{g->arcs[i][j]=1;g->arcs[j][i]=1;}}}void printMG(MGraph *g) {int i,j;for (i=0;i<g->vexnum;i++){for (j=0;j<g->vexnum;j++)printf(" %d",g->arcs[i][j]);printf("\n");}printf("\n");}main(){int i,j;int fg;MGraph *g1;g1=(MGraph*)malloc(sizeof(MGraph));printf("1:创建无向图的邻接矩阵\n\n");creat_MGraph1(g1);printf("\n此图的邻接矩阵为:\n"); printMG(g1);}2、邻接链表:#include<stdio.h>#include<malloc.h>#define MAX_SIZE 10typedef struct node{int vertex;struct node *next;}node,adjlist[MAX_SIZE];adjlist g;int visited[MAX_SIZE+1];int que[MAX_SIZE+1];void creat(){int n,e;int i;int start,end;node *p,*q,*pp,*qq;printf("输入无向图的顶点数和边数:");scanf("%d%d",&n,&e);for(i = 1; i <= n ; i++){visited[i] = 0;g[i].vertex = i;g[i].next = NULL;}printf("依次输入边:\n");for(i = 1; i <= e ; i++){scanf("%d%d",&start,&end);p=(node *)malloc(sizeof(node));p->vertex = end;p->next = NULL;q = &g[start];while(q->next)q = q->next;q->next = p;p1=(node*)malloc(sizeof(node));p1->vertex = start;p1->next = NULL;q1 = &g[end];while(qq->next)q1 = q1->next;q1->next = p1;}}void bfs(int vi){int front,rear,v;node *p;front =0;rear = 1;visited[vi] = 1;que[0] = vi;printf("%d ",vi);while(front != rear){v = que[front];p = g[v].next;while(p){if(!visited[p->vertex]){visited[p->vertex]= 1;printf("%d",p->vertex);que[rear++] = p->vertex;}p = p->next;}front++;}}int main(){creat();bfs(1);printf("\n");return 0;}五.实验心得与体会:(1)通过这次实验,使我基本上掌握了图的存储和遍历,让我弄清楚了如何用邻接矩阵和邻接链表对图进行存储(2)深度优先遍历和广度优先遍历都有着各自的优点,通过程序逐步调试,可以慢慢的理解这两种遍历方法的内涵和巧妙之处。
数据结构图的遍历实验报告
实验项目名称:图的遍历一、实验目的应用所学的知识分析问题、解决问题,学会用建立图并对其进行遍历,提高实际编程能力及程序调试能力。
二、实验内容问题描述:建立有向图,并用深度优先搜索和广度优先搜素。
输入图中节点的个数和边的个数,能够打印出用邻接表或邻接矩阵表示的图的储存结构。
三、实验仪器与设备计算机,Code::Blocks。
四、实验原理用邻接表存储一个图,递归方法深度搜索和用队列进行广度搜索,并输出遍历的结果。
五、实验程序及结果#define INFINITY 10000 /*无穷大*/#define MAX_VERTEX_NUM 40#define MAX 40#include<>#include<>#include<>#include<>typedef struct ArCell{int adj;}ArCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{ char name[20];}infotype;{ infotype vexs[MAX_VERTEX_NUM];AdjMatrix arcs;int vexnum,arcnum;}MGraph;int LocateVex(MGraph *G,char* v){ int c = -1,i;for(i=0;i<G->vexnum;i++)if(strcmp(v,G->vexs[i].name)==0){ c=i; break;}return c;}MGraph * CreatUDN(MGraph *G)d:",i+1);scanf("%s",G->vexs[i].name);}for(i=0;i<G->vexnum;i++)for(j=0;j<G->vexnum;j++)G->arcs[i][j].adj=INFINITY;printf("请输入一条边依附的两个顶点和权值:\n");for(k=0;k<G->arcnum;k++){printf("第%d条边:\n",k+1);printf("起始结点:");scanf("%s",v1);printf("结束结点:");scanf("%s",v2);dj=w;G->arcs[j][i]=G->arcs[i][j];}}return G;}int FirstAdjVex(MGraph *G,int v){int i;if(v<=0 && v<G->vexnum){ dj!=INFINITY)return i;}return -1;}void VisitFunc(MGraph *G,int v){printf("%s ",G->vexs[v].name);}int NextAdjVex(MGraph *G,int v,int w){int k;if(v>=0 && v<G->vexnum && w>=0 && w<G->vexnum)dj!=INFINITY) return k;return -1;}int visited[MAX];void DFS(MGraph *G,int v)//从第v个顶点出发递归地深度优先遍历图G {int w;visited[v]=1;VisitFunc(G,v);//访问第v个结点for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))if(!visited[w]){DFS(G,w);printf("%d ",G->arcs[v][w]);}}void DFSTraverse(MGraph *G,char *s)//深度优先遍历{int v,k;for(v=0;v<G->vexnum;v++)visited[v]=0;k=LocateVex(G,s);if(k>=0&&k<G->vexnum){for(v=k;v>=0;v--){if(!visited[v])DFS(G,v);}for(v=k+1;v<G->vexnum;v++)if(!visited[v])DFS(G,v);}}typedef struct Qnode{int vexnum;struct Qnode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front;QueuePtr rear;}LinkQueue;int InitQueue(LinkQueue *Q){Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));if(!Q->front)exit(0);Q->front->next=NULL;return 1;}void EnQueue(LinkQueue *Q,int a )QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p)exit(0);p->vexnum=a;p->next=NULL;Q->rear->next=p;Q->rear=p;}int DeQueue(LinkQueue *Q,int *v){ QueuePtr p;if(Q->front==Q->rear){printf("结点不存在!\n");exit(0);}p=Q->front->next;*v=p->vexnum;Q->front->next=p->next;if(Q->rear==p)Q->front=Q->rear;return *v;}int QueueEmpty(LinkQueue *Q){if(Q->rear==Q->front)return 0;return 1;}int Visited[MAX];void BFSTraverse(MGraph *G,char *str)//广度优先遍历{int w,u,v,k;LinkQueue Q,q;for(v=0;v<G->vexnum;v++) Visited[v]=0;InitQueue(&Q);InitQueue(&q);k=LocateVex(G,str);for(v=k;v>=0;v--)if(!Visited[v]){Visited[v]=1;VisitFunc(G,v);EnQueue(&Q,v);//v入队while(!QueueEmpty(&Q)){DeQueue(&Q,&u);//出队for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))if(!Visited[w]){VisitFunc(G,v);EnQueue(&Q,w);}}}for(v=k+1;v<G->vexnum;v++)if(!Visited[v]){Visited[v]=1;VisitFunc(G,v);EnQueue(&Q,v);//v入队while(!QueueEmpty(&Q)){DeQueue(&Q,&u);//出队for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w)) if(!Visited[w]){Visited[w]=1;VisitFunc(G,v);EnQueue(&Q,w);}}}}void main(){MGraph *G,b;char v[10];G=CreatUDN(&b);printf("请输入起始结点名称:");scanf("%s",v);printf("\n深度优先遍历:\n");DFSTraverse(G,v);printf("\n广度优先遍历:\n");BFSTraverse(G,v);getch();}六、实验总结实验要求输入图中节点的个数和边的个数,能够打印出用邻接表或邻接矩阵表示的图的储存结构。
实验七 图的建立及其应用
实验七 图的建立及其应用一、实验目的:(1)掌握图的存储思想及其存储实现。
(2)掌握图的深度、广度优先遍历算法思想及其程序实现。
(3)掌握图的常见应用算法的思想及其程序实现。
(4)理解有向无环图、最短路径等算法二、实验要求1.将算法中的横线内容填写完整,使程序能正常运行2.在主函数中设计一个简单的菜单,具有如下功能。
(1)建立有向图的邻接表;(2)输出邻接表;3.实现图的深度优先遍历的算法(选做)4.完成实际应用(选做)三、实验原理1、图(GRAPH )是一种复杂的数据结构,结点之间的关系可以是任意的,由此图的应用极为广泛,已经渗透到如物理、化学、电讯工程、计算机科学等领域。
2、图存储结构:邻接矩阵表示法和邻接表表示法,本次实验图主要以邻接表进行存储。
用邻接矩阵表示法表示图如下图所示:0 1 0 1 A = 1 0 1 10 1 0 01 0 0 1一个无向图的邻接矩阵表示无向图对应的邻接表表示如下图所示:序号一个无向图的的邻接表表示四、实验程序说明图类型定义typedef struct Node{int dest; //邻接边的弧头结点序号struct Node *next;}Edge; //邻接边单链表的结点的结构体typedef struct{DataType data; //图顶点Edge *adj; //邻接边的头指针}AdjLHeight; //数组的数据元素类型结构体typedef struct{AdjLHeight a[MaxVertices]; //邻接表数组int numOfVerts; //结点个数int numOfEdges; //边个数}AdjLGraph; //邻接表结构体五、参考程序#include<malloc.h> /* malloc()等*/#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<process.h> /* exit() */typedef char DataType;#define MaxVertices 10void AdjInitiate(AdjLGraph *G)//初始化图{int i;G->numOfEdges=0;G->numOfVerts=0;for(i=0;i<MaxVertices;i++){G->a[i].adj = NULL ;//设置邻接边单链表头指针初值}}void InsertVertex(AdjLGraph *G,int i,DataType vertex)//在图中的第i个位置插入顶点数据元素vertex{if(i>=0&&i<MaxVertices){G->a[i].data =vertex; //存储顶点数据元素vertexG->numOfVerts++ ; //个数加1 }else printf("结点越界");}void InsertEdge(AdjLGraph *G,int v1,int v2)//在图中加入边<v1,v2>的信息{Edge *p;if(v1<0||v1>=G->numOfVerts||v2<0||v2>=G->numOfVerts){printf("参数v1和v2越界出错!");exit(0);}p=(Edge*)malloc(sizeof(Edge));//申请邻接边单链表结点空间p->dest=v2; //设置邻接边弧头序号p->next = G->a[v1].adj ; //新结点插入邻接表的表头G->a[v1].adj = p ; //头指针指向新的单链表表头G->numOfEdges++; //边个数加1}int GetFirstVex(AdjLGraph G,int v)//取图G中结点v的第一个邻接结点{Edge *p;if(v<0||v>=G.numOfVerts){printf("参数出错!");exit(0);}p=G.a[v].adj;if(p!=NULL)return p->dest;else return -1;}int GetNextVex(AdjLGraph G,int v1,int v2)//取图G中结点v1的邻接结点v2的下一个邻接结点{Edge *p;if(v1<0||v1>=G.numOfVerts||v2<0||v2>=G.numOfVerts){printf("参数v1和v2越界出错!");exit(0);}p=G.a[v1].adj;while(p!=NULL){if(p->dest!=v2){p = p->next ;continue;}else break;}p=p->next;if(p!=NULL) return p->dest;else return -1;}void main(void){int i,k,n,e,v1,v2;char c1;Edge *p;AdjLGraph G;AdjInitiate(&G);printf("输入图的顶点数\n");scanf("%d",&n);getchar();printf("输入图顶点为(请输入字母)\n");for(i=0;i<n;i++){scanf("%c",&c1); //通过键盘,输入图的顶点getchar();InsertVertex(&G,i,c1) ; //插入顶点}printf("输入图的边数\n");scanf("%d",&e);printf("如果边v1->v2,则输入0,1\n");for(k=0;k<e;k++){printf("输入边的顶点为(请输入数字):");scanf("%d,%d",&v1,&v2); //通过键盘,输入图的邻接边的两个顶点InsertEdge(&G,v1,v2) ; //插入边}for(i=0;i<n;i++)//输出邻接表{printf("%c\t",G.a[i].data);p=G.a[i].adj;if(p==NULL) printf("数据为空");else{ while(p!=NULL){printf("%d->",p->dest);p=p->next;}printf("^");}printf("\n");}}序号六、应用题(一)校园导游图实验内容:1、设计学生所在学校的校园平面图,所含景点不少于10个。
C语言_数据结构_实验7_图的创建与遍历 2
实验五(1):图的创建与遍历
1.实验目的:
1.掌握图的含义;
2.掌握用邻接矩阵和邻接表的方法描述图的存储结构;
3.理解并掌握深度优先遍历和广度优先遍历的存储结构。
2.实验内容:
(1)以邻接矩阵为存储结构,实现连通有向图(下图)的所有顶点出度与入度的计算。
(2)设计两个算法分别实现深度优先遍历和广度优先遍历。
1 调试程序。
设计一个有向图和一个无向图,任选一种存储结构,完成有向
图和无向图的DFS(深度优先遍历)和BFS(广度优先遍历)的操作。
邻接矩阵作为存储结构的运行结果:
邻接链表作为存储结构的运行结果:
实验报告要求
画出你所设计的图,写出两种方法的遍历序列。
邻接矩阵:
V0 V1 V2 V3 V4 V5 V6 V7
V0 0 1 1 0 0 0 0 0 V1 1 0 0 1 1 0 0 0 V2 1 0 0 0 0 1 1 0 V3 0 1 0 0 0 0 0 1 V4 1 0 0 0 0 0 0 1 V5 0 1 0 0 0 0 1 0 V6 0 1 0 0 0 1 0 0 V7 0
1
1
V6 V4 V5 V7 V2 V3 V1 V0 图G 的示例
V0 0 2 1 ^
V1 1 4 3 ^ 0 ^ V2 2 6 5 0 ^ V3 3 4 1 ^
V4 4 7 1 ^
V5 5 6 2 ^
V6 6 5 2 ^
V7 7 4 3 ^
深度遍历为:0→2→6→5→1→4→7→3
广度遍历为:3→7→1→4→0→2→6→5。
数据结构课程设计-图的遍历
数据结构课程设计-图的遍历1. 介绍图是一种非线性数据结构,它由节点和边组成。
在图中,节点可以表示任何对象,而边则表示节点之间的关系。
图可以用于表示许多现实世界中的问题,例如社交网络、电路板和道路网络。
图遍历是图算法的基础,它是指从图的一个特定节点出发,按照一定顺序访问图中所有节点的过程。
在这篇文章中,我们将讨论基本的图遍历算法,包括深度优先遍历(DFS)和广度优先遍历(BFS)。
2. 深度优先遍历 (DFS)深度优先遍历是一种用于遍历或搜索树或图的算法。
在深度优先遍历中,我们先访问一个顶点,然后沿着这个顶点下一条未访问的边走到下一个顶点,直到遇到一个没有未访问的邻居为止。
然后我们回溯到之前的节点,并访问该节点的另一个未访问的邻居。
我们重复这个过程,直到所有的节点都被访问。
在深度优先遍历中,每个节点仅被访问一次。
深度优先遍历有两种实现方式:递归实现和迭代实现。
递归实现方式是深度优先遍历的传统实现方式。
当对一个节点进行深度优先遍历时,我们首先访问这个节点,然后递归地遍历它的每一个邻居节点。
这个过程会一直持续到当前节点的所有邻居节点都被访问到为止。
下面是递归实现方式的伪代码:void DFS(Node node){visit(node);for (Node neighbor : node.neighbors) {if (!neighbor.visited) {DFS(neighbor);}}}另一种实现方式是使用栈来模拟递归过程,称为迭代实现方式。
在这种实现方式中,我们使用深度优先搜索的方式逐步遍历节点。
在遍历过程中,我们将每个节点的邻居节点加入到栈中,以便后续处理。
下面是迭代实现方式的伪代码:void DFS(Node node){Stack stack = new Stack();stack.push(node);while (!stack.isEmpty()) {Node currentNode = stack.pop();if (!currentNode.visited) {visit(currentNode);for (Node neighbor : currentNode.neighbors) {stack.push(neighbor);}}}}3. 广度优先遍历 (BFS)广度优先遍历是另一种图遍历算法。
七图
n图的基本概念n图的存储结构n图的遍历与连通性n最小生成树n最短路径n活动网络7.1图的基本概念n图定义图是由顶点集合(vertex)及顶点间的关系集合组成的一种数据结构:Graph=( V, E )其中V= { x| x ∈某个数据对象}是顶点的有穷非空集合;E= {(x, y) |x, y ∈V }或E= {<x, y>|x, y ∈V&& Path(x, y)}是顶点之间关系的有穷集合,也叫做边(edge)集合。
Path(x, y)表示从x 到y 的一条单向通路, 它是有方向的。
n有向图与无向图在有向图中,顶点对<x, y>是有序的。
在无向图中,顶点对(x, y)是无序的。
n完全图若有n 个顶点的无向图有n(n-1)/2 条边, 则此图为完全无向图。
有n 个顶点的有向图有n(n-1) 条边, 则此图为完全有向图。
邻接顶点如果(u, v) 是E(G) 中的一条边,则称u 与v 互为邻接顶点。
n权某些图的边具有与它相关的数,称之为权。
这种带权图叫做网络。
n 子图设有两个图G =(V ,E )和G ,=(V ,,E ,)。
若V ,⊆V 且E,⊆E ,则称图G ,是图G 的子图。
n顶点v 的入度是以v 为终点的有向边的条数, 记作ID(v ); n顶点v 的出度是以v 为始点的有向边的条数, 记作OD(v )。
n 在有向图中, 顶点的度等于该顶点的入度与出度之和。
n 路径在图G =(V , E ) 中, 若从顶点v i 出发, 沿一些边经过一些顶点v p 1, v p 2, …, v pm ,到达顶点v j 。
则称顶点序列( v i v p 1 v p 2 ... v pm v j )为从顶点v i 到顶点v j 的路径。
它经过的边(v i , v p 1)、(v p 1, v p 2)、...、(v pm ,v j )应是属于E 的边。
n 路径长度u 非带权图的路径长度是指此路径上边的条数。
数据结构实验八、图的建立和遍历
}SqQueue;
void InitQueue(SqQueue &Q)
{Q.front =Q.rear =0;
}
int QueueEmpty(SqQueue &Q)
{if(Q.front==Q.rear) return 1;
else return 0;
}
int QueueFull(SqQueue &Q)
SqQueue Q;
InitQueue(Q); //初始化队列
cout<<"广度优先遍历序列如下:"<<endl;
if (G.Visited[Starti]==0) //尚未访问
{ G.Visited[Starti] = 1;
cout<<"访问"<<G.V[Starti]<<endl;//访问u
EnQueue(Q, Starti); // v入队列
for(k=1;k<=G1.e;k++)
{
cout<<"请输入第"<<k<<"边<<"请输入第"<<k<<"边的终点序号:";
cin>>j;
G1.E[i][j]=1;
if( G1.flag==0 ) G1.E[j][i]=G1.E[i][j];
}
cout<<"图对应的邻接矩阵如下:"<<endl;
山东英才职业技工学校实验报告
系:__计算机_____成绩_______________
数据结构实验七 图及图的操作实验
实验报告七图及图的操作实验班级: 2010XXX 姓名: HoogLe 学号: 2010XXXX 专业: XXXX*****************一、实验目的:1、掌握图的基本概念和术语2、掌握图的存储结构及创建算法。
3、掌握图的遍历算法(递归算法)。
二、实验内容:1、图邻接矩阵存储结构表示及基本操作算法实现[实现提示] (同时可参见教材及ppt上的算法)函数、类名称等可自定义,部分变量请加上学号后3位。
也可自行对类中所定义的操作进行扩展。
所加载的库函数或常量定义及类的定义:(1)邻接矩阵存储结构类定义:自定义如下:#include <iostream>using namespace std;const int MaxSize=12;const int INFINITY=65535;template<class T>class Mgraph{public:Mgraph(T a[],int n,int e);//构造函数,a[]表示节点数组,n表示顶点个数,e表示边数void printGraph(); //输出void BFS(int v,int visited[]); //广度优先搜索private:T vertex[MaxSize];int arc[MaxSize][MaxSize];int vertexNum,arcNum;void createUG(T a[],int n,int e); //无向图void createUW(T a[],int n,int e); //无向网void createHG(T a[],int n,int e); //有向图void createHW(T a[],int n,int e); //有向网};template<class T>Mgraph<T>::Mgraph(T a[],int n,int e){int kind;cout<<"请输入所需创建的图的类型:"<<endl;cout<<"1.无向图"<<endl;cout<<"2.无向网"<<endl;cout<<"3.有向图"<<endl;cout<<"4.有向网"<<endl;cin>>kind;switch(kind){case 1:createUG(a,n,e);break;case 2:createUW(a,n,e);break;case 3:createHG(a,n,e);break;case 4:createHW(a,n,e);break;default:cout<<"输入错误!"<<endl;}}(2)创建邻接矩阵算法创建无向图邻接矩阵算法:template <class T>void Mgraph<T>::createUG(T a[],int n,int e){//创建无向图vertexNum=n; //顶点数arcNum=e; //边数int i,j,k;for (i=0; i<vertexNum; i++)vertex[i]=a[i];for (i=0; i<vertexNum; i++) //初始化邻接矩阵for (j=0; j<vertexNum; j++)arc[i][j]=0;for (k=0; k<arcNum; k++)//依次输入每一条边,并修改邻接矩阵的相应元素{ cout<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2):";cin>>i>>j; //边依附的两个顶点的序号arc[i-1][j-1]=1; //置有边标志arc[j-1][i-1]=1;}}创建无向网邻接矩阵算法:无向网的创建:template <class T>void Mgraph<T>::createUW(T a[],int n,int e){//创建无向网int w;//权值vertexNum=n; //顶点数arcNum=e; //边数int i,j,k;for (i=0; i<vertexNum; i++)vertex[i]=a[i];for (i=0; i<vertexNum; i++) //初始化邻接矩阵for (j=0; j<vertexNum; j++)arc[i][j]=INFINITY;for (k=0; k<arcNum; k++)//依次输入每一条边,并修改邻接矩阵的相应元素{cout<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2 权值):";cin>>i>>j>>w;//边依附的两个顶点的序号arc[i-1][j-1]=w; //置有边标志arc[j-1][i-1]=w;}}创建有向图邻接矩阵算法:template <class T>void Mgraph<T>::createHG(T a[],int n,int e){//创建无向图vertexNum=n; //顶点数arcNum=e; //边数int i,j,k;for (i=0; i<vertexNum; i++)vertex[i]=a[i];for (i=0; i<vertexNum; i++) //初始化邻接矩阵for (j=0; j<vertexNum; j++)arc[i][j]=0;for (k=0; k<arcNum; k++)//依次输入每一条边,并修改邻接矩阵的相应元素{ cout<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2):";cin>>i>>j; //边依附的两个顶点的序号arc[i-1][j-1]=1; //置有边标志}}创建有向网邻接矩阵算法:template <class T>void Mgraph<T>::createHW(T a[],int n,int e){//创建无向图vertexNum=n; //顶点数arcNum=e; //边数int i,j,k;int w;for (i=0; i<vertexNum; i++)vertex[i]=a[i];for (i=0; i<vertexNum; i++) //初始化邻接矩阵for (j=0; j<vertexNum; j++)arc[i][j]=0;for (k=0; k<arcNum; k++)//依次输入每一条边,并修改邻接矩阵的相应元素{cout<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2 权值):";cin>>i>>j>>w; //边依附的两个顶点的序号arc[i-1][j-1]=w; //置有边标志}}(3)输出邻接矩阵结果算法template <class T>void Mgraph<T>::printGraph(){//输出邻接矩阵int i,j;for(i=0;i<vertexNum;i++){for(j=0;j<vertexNum;j++)cout<<arc[i][j]<<ends;cout<<endl;}}测试结果粘贴如下:void main(){int a[6]={1,2,3,4,5,6};Graph<int> graph1(a,6,5);graph1.printGraph();}2、图邻接表存储结构表示及基本操作算法实现[实现提示]函数、类名称等可自定义,部分变量请加上学号后3位。
数据结构图的遍历实验报告
题目:图的遍历的实现完成日期:2011.12.22一、需求分析1.本演示程序中,输入的数据类型均为整型数据,不允许输入字符等其他数据类型,且需要按照提示内容进行输入,成对的关系数据必须在所建立的图中已经存在对应的结点。
2.演示程序以用户和计算机的对话方式执行,在计算机终端上显示的提示信息的说明下,按照要求输入数据,运算结果在其后显示。
3.本程序实现分别基于邻接矩阵和邻接表存储结构的有、无向图,有、无向网的建立和遍历。
遍历分DFS和BFS两种算法,并分别以递归和非递归形式实现。
4.测试数据:(1)无向图结点数4 弧数3 结点:1 2 3 4 结点关系:1 2;1 3;2 4(2)有向图结点数6 弧数6 结点:1 2 3 4 5 6 结点关系:1 2;1 3;2 4;3 5;3 6;2 5 二、概要设计为实现上述程序功能,图的存储结构分为邻接矩阵和邻接表两种。
遍历过程中借助了栈和队列的存储结构。
1.邻接矩阵存储结构的图定义:ADT mgraph{数据对象V:V是具有相同特性的的数据元素的集合,成为顶点集。
数据关系R:R={VR}VR={ <v,w>| v,w є V且P(v,w),<v,w>表示从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}基本操作P:locatevex(G, mes);初始条件:图G存在,mes和G中顶点有相同的特征。
操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回其他信息。
createudn( & G);初始条件:图G 存在。
操作结果:创建无向图。
createdn( & G);初始条件:图G 存在。
操作结果:创建有向图。
createudg( & G);初始条件:图G 存在。
操作结果:创建无向网。
createdg(& G);初始条件:图G 存在。
操作结果:创建有向网。
DFS(G,v);初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。
数据结构上机实验报告有向图的邻接表的建立及遍历
《数据构造》上机试验汇报—有向图旳邻接表旳建立及遍历福州大学数计学院《数据构造》上机试验汇报专业和班级:信息计算科学与应用数学6班学号姓名成绩试验名称图旳有关操作试验内容有向图旳邻接表旳建立及遍历实【试验目旳】验 ,(掌握图旳存储思想及其存储实现。
目 ,(掌握图旳深度、广度优先遍历算法思想及其程序实现。
旳 ,(掌握图旳常见应用算法旳思想及其程序实现。
和要求【试验内容】1. 键盘输入数据,建立一种有向图旳邻接表。
2(在有向图旳邻接表旳基础上计算各顶点旳度。
3(采用邻接表存储实既有向图旳深度优先遍历。
4(采用邻接表存储实既有向图旳广度优先遍历。
【重要程序】#include<stdio.h>#include<stdlib.h>#include<conio.h>#define MAX_VERTEX_NUM 20#define OK 1#define ERROR 0#define OVERFLOW 0int visited[MAX_VERTEX_NUM];typedef struct ArcNode //表结点问 { 题 int adjvex; //该弧所指向旳顶点旳位置描 struct ArcNode *nextarc;//指向下一条弧旳指针char *info; //该弧有关信息旳指针述 }ArcNode; 和主 typedef struct VNode //头结点{ 要 char data; //顶点信息步 ArcNode *firstarc; //第一种表结点旳地址,指向第一条依附顶骤点旳弧旳指针}VNode,AdjList[MAX_VERTEX_NUM]; //头结点,头结点旳次序表AdjList[]类型typedef struct //图构造{AdjList vertices;int vexnum,arcnum; //图旳目前顶点数与弧数}ALGraph;typedef struct QNode //用于BFS遍历旳附设链队列结点构造{int data;struct QNode *next;}QNode,*QueuePtr;typedef struct //链队列{QueuePtr rear;}LinkQueue;int InitQueue(LinkQueue &Q) //初始化链队{Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));if(!Q.front) exit(OVERFLOW);Q.front->next=NULL;return OK;}int EnQueue(LinkQueue &Q,int e) //元素e入队 {QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->next=NULL;p->data=e;Q.rear->next=p;Q.rear=p;return OK;}int DeQueue(LinkQueue &Q,int &e)//队首元素出队,由e返回其值{QueuePtr p;if(Q.front==Q.rear) exit(OVERFLOW);e=p->data;Q.front->next=p->next;if(Q.rear==p)Q.rear=Q.front;free(p);return OK;}int EmptyQueue(LinkQueue Q) //判断队列Q与否为空{if(Q.front==Q.rear)return 1;return 0;}int LocateVex(ALGraph G,char v) //查找值为v旳顶点在顶点向量G.vexs[]中旳位置{int i;for(i=0;i<G.vexnum;i++)if(v==G.vertices[i].data)return i;return -1;}int FirstAdjVex(ALGraph G,char v)//返回v旳第一种邻接顶点旳序号{int i;ArcNode *p;i=LocateVex(G,v); //i为顶点v在图G中旳序号if(i==-1)return -1;p=G.vertices[i].firstarc;if(p)return p->adjvex;elsereturn -1;}int NextAdjVex(ALGraph G,char v,char w)//返回v旳(相对于w)旳下一种邻接顶点旳序号{int i,j;ArcNode *p,*q;i=LocateVex(G,v);j=LocateVex(G,w);if(i==-1||j==-1||i==j)return -1;p=G.vertices[i].firstarc; //p指向v旳邻接顶点链表中旳第一种邻接顶点while(p->nextarc&&p->adjvex!=j) //找到邻接顶点wp=p->nextarc;if(p->nextarc) //找到邻接顶点w,且w非v旳最后一种邻接顶点{q=p->nextarc;return q->adjvex; //返回v旳(相对于w)旳下一种邻接顶点旳序号}elsereturn -1; //没有找到w或w是v旳最终一种邻接顶点}int Visit(char v){printf("%c ",v);return OK;}int CreateDG(ALGraph &G) //采用邻接表表达,构造有向图G {int v,e,i,j,t;ArcNode *p,*q;char tail,head;printf("输入顶点个数:");scanf("%d",&v);if(v<0)return ERROR;G.vexnum=v;printf("输入弧旳条数:");scanf("%d",&e);if(e<0)return ERROR;G.arcnum=e;printf("建立DG:\n");for(t=0;t<G.vexnum;t++) //建立头结点次序表{fflush(stdin);printf("输入%d旳信息:",t+1);scanf("%c",&G.vertices[t].data);G.vertices[t].firstarc=NULL; //初始化该头结点指针域}for(t=0;t<G.arcnum;t++) //建立表结点链表(每个顶点旳邻接顶点链表){fflush(stdin);printf("输入弧旳信息(弧尾-弧头)");scanf("%c%*c%c",&tail,&head);i=LocateVex(G,tail);j=LocateVex(G,head);if(i==-1||j==-1||i==j)return ERROR;p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->info=NULL;p->nextarc=NULL;if(!G.vertices[i].firstarc)G.vertices[i].firstarc=p;else{//找尾结点for(q=G.vertices[i].firstarc;q->nextarc;q=q->nextarc);q->nextarc=p; //插入到链表尾}}}int DFS(ALGraph G,int v) //从第v个顶点出发,递归旳深度优先遍历有向图G{int w;visited[v]=-1;printf("%c ",G.vertices[v].data);w=FirstAdjVex(G,G.vertices[v].data);for(;w>=0;w=NextAdjVex(G,G.vertices[v].data,G.vertices[w].data)) if(!visited[w])DFS(G,w); //对v旳尚未访问旳邻接顶点w递归调用DFS()return OK;}int DFSTraverse(ALGraph G) //深度优先搜索遍历图G { int i;for(i=0;i<G.vexnum;i++)visited[i]=0;for(i=0;i<G.vexnum;i++)if(!visited[i])DFS(G,i);return OK;}int BFSTraverse(ALGraph G,int(*visit)(char v)) { LinkQueue Q;int v,w,u;for(v=0;v<G.vexnum;v++)visited[v]=0;InitQueue(Q);for(v=0;v<G.vexnum;v++){if(!visited[v]){visited[v]=1;Visit(G.vertices[v].data);}EnQueue(Q,v);while(!EmptyQueue(Q)){DeQueue(Q,u);for(w=FirstAdjVex(G,G.vertices[u].data);w>0;w=NextAdjVex (G,G.vertices[u].data,G.vertices[w].data))if(!visited[w]){visited[w]=1;Visit(G.vertices[w].data);EnQueue(Q,w);}}}return OK;}void main(){ALGraph G;printf("建立有向图G\n");if(CreateDG(G)){printf("深度优先搜索旳次序:"); DFSTraverse(G);printf("\n");printf("广度优先搜索旳次序:"); BFSTraverse(G,Visit);}printf("\n");}【成果截图】。
数据结构实验报告图的遍历
数据结构实验报告图的遍历数据结构实验报告:图的遍历引言在计算机科学中,图是一种重要的数据结构,它由节点和边组成,用于表示不同实体之间的关系。
图的遍历是一种重要的操作,它可以帮助我们了解图中节点之间的连接关系,以及找到特定节点的路径。
在本实验中,我们将讨论图的遍历算法,并通过实验验证其正确性和效率。
深度优先搜索(DFS)深度优先搜索是一种常用的图遍历算法,它通过递归或栈的方式来遍历图中的节点。
在实验中,我们实现了深度优先搜索算法,并对其进行了测试。
实验结果表明,深度优先搜索算法能够正确地遍历图中的所有节点,并找到指定节点的路径。
此外,我们还对算法的时间复杂度进行了分析,验证了其在不同规模图上的性能表现。
广度优先搜索(BFS)广度优先搜索是另一种常用的图遍历算法,它通过队列的方式来遍历图中的节点。
在实验中,我们也实现了广度优先搜索算法,并对其进行了测试。
实验结果显示,广度优先搜索算法同样能够正确地遍历图中的所有节点,并找到指定节点的路径。
我们还对算法的时间复杂度进行了分析,发现其在不同规模图上的性能表现与深度优先搜索算法相近。
实验结论通过本次实验,我们深入了解了图的遍历算法,并验证了其在不同规模图上的正确性和效率。
我们发现深度优先搜索和广度优先搜索算法都能够很好地应用于图的遍历操作,且在不同情况下都有良好的性能表现。
这些算法的实现和测试为我们进一步深入研究图的相关问题提供了重要的基础。
总结图的遍历是图算法中的重要操作,它为我们提供了了解图结构和节点之间关系的重要手段。
本次实验中,我们实现并测试了深度优先搜索和广度优先搜索算法,验证了它们的正确性和效率。
我们相信这些算法的研究和应用将为我们在图相关问题的研究中提供重要的帮助。
7图的遍历
数据结构
广度优先搜索算法
void BFSTraverse(Graph G, Status (* visit)(int v)) { for(v=0; v<G.vexnum; ++v) visited[v] = FALSE; IntiQueque(Q); for(v=0; v<G.vexnum; ++v) if(!visited[v]) { visited[v] = TRUE; Visit (v); EnQueue(Q,v); while(!QueueEmpty(Q)){ DeQueue(Q,u); for(w=FirstAdjVex(G, u);w;w = NextAdjVex(G,u,w)) if(!visited[w]) {visited[w]=TRUE; visited(w); EnQueue(G,w); } } } 7 数据结构 }
void DFSTree(Graph G,int v ,CSTree &T) { //从第 个顶点出发深度优先遍历图G 建立以T //从第v个顶点出发深度优先遍历图G,建立以T为根的生成 从第v 树 visited[v]=TRUE; first=TRUE; for(w=FirstAdjVex(G,v);w>=0; w=NextAdjVex(G,v,w)) if(!visited[w]) p=(CSTree)malloc(sizeof)CSNode));//分配孩子结点 { p=(CSTree)malloc(sizeof)CSNode));//分配孩子结点 *p={GetVex(G,w),NULL,NULL}; //w 的第一个未被访问的邻接顶点, if (first) //w是v的第一个未被访问的邻接顶点,作 为 根的左孩子结点 T{ T->lchild=p; first=FALSE; } //w 的其它未被访问的邻接顶点, else { //w是v的其它未被访问的邻接顶点,作为上一 邻 接顶点的右兄弟 q->nextsibling=p; } q=p; D 从第w //从第 DFSTree(G,w,q); //从第w个顶点出发深度优先遍历 A 图 G,建立生成子树q 建立生成子树q 12 数据结构 B C E }
图的建立与遍历实验报告
图的建立与遍历实验报告------------图的建立与遍历姓名:曹庆松班级:1104学号:1111611512实验日期:2012.10.15报告撰写日期:2012.10.16一、实验目的:1、熟悉图的概念、存储结构和遍历方法。
2、以邻接表为存储结构,掌握无向图的基本操作和实现方法。
3、以邻接表为存储结构,掌握无向图的深度优先遍历的算法实现。
二、实验内容:以邻接表为存储结构,编写程序实现。
1、要求通过键盘输入图的顶点,以及每一条边的两个顶点从而建立无向。
为了简化实验,顶点用数字表示。
2、在以上实验的基础上,实现无向图的深度优先遍历算法。
要求以用户给定的顶点为起始点,显示深度优先遍历的次序。
三、程序代码及结果展示:#include "stdafx.h"#include<stdio.h>#include<stdlib.h>#include <malloc.h>#define MAX_VERTER_NUM 20typedef struct ArcNode{ //表节点int adjvex; //邻接点struct ArcNode *nextarc; //指向下一条弧的指针}ArcNode;typedef struct VNode{ //头结点int data; //定点信息ArcNode * firstarc; //指向第一个依附该顶点的弧的指针}VNode,AdjList[MAX_VERTER_NUM];typedef struct{ //图AdjList vertices; //顶int vexnum,arcnum;//图的顶点数和弧数int Kind;// 图的种类标志}ALGraph;// 对图 G 作深度优先遍历int LocateVex(ALGraph * G,int v) //寻找节点V的位置 { int k,n;for(k=0;k<G->vexnum;k++){ if(G->vertices[k].data==v){n=k;break;}}return n;}int n=1;int visited[MAX_VERTER_NUM]; void DFS(ALGraph *G,int v)//递归调用{ArcNode *p;>vertices[v].firstarc; p=G-if(n<G->vexnum+1){printf(" V%d ",G->vertices[v].data);n++;}visited[v]=1;while(p){if(!visited[p->adjvex])DFS(G,p->adjvex);p=p->nextarc;}}void DFSVisited(ALGraph * G)//深度遍历{int v;int n;printf("请输入遍历的起始的顶点:");scanf("%d",&n);n"); printf("递归深度优先遍历点顺序: \DFS(G,n-1);for(v=0;v<G->vexnum;v++)visited[v]=0;for(v=0;v<G->vexnum;v++)if(!visited[v])DFS(G,v);}void Insertadj(ALGraph * G,int i,int j) //插入邻接点的下标 { ArcNode *a1,*a2;a1=(ArcNode *)malloc(sizeof(ArcNode));a1->adjvex=j;a1->nextarc=NULL;if(G->vertices[i].firstarc==NULL){G->vertices[i].firstarc=a1;}else{a2=G->vertices[i].firstarc;while(a2->nextarc){a2=a2->nextarc;}a2->nextarc=a1;}}void Init_ALGraph(ALGraph * G) //初始化图并建图 { int v,v1,v2,i,j,q,p;int m=0;printf("请输入顶点数:");scanf("%d",&G->vexnum);printf("请输入边数:");scanf("%d",&G->arcnum);for(v=0;v<G->vexnum;v++){printf("顶点 V%d:",(v+1));scanf("%d",&(G->vertices[v].data));>vertices[v].firstarc=NULL; G-}for(v=0;v<G->arcnum;v++) {printf("请输入点点: ");scanf("%d%d",&v1,&v2);i=LocateVex(G,v1); //v1的位置j=LocateVex(G,v2); //v2的位置Insertadj(G,i,j);Insertadj(G,j,i);}}int main(int argc,char **argv) {ALGraph G;Init_ALGraph(&G);//初始化图并建图DFSVisited(&G);//深度优先遍历printf("\n");return 0;}四、实验总结:通过本实验,我对图的存储结构、图的遍历等有了比较深的理解与运用,图的遍历和树的遍历很类似,但是却比树的遍历复杂很多。
图的建立与遍历实验报告
实验图的建立与遍历姓名:曹国君梁辰唐琪皓黄悦班级:信息1班学号:09125676 09125675 09125672 09125673 实验时间:第9周1.问题描述输入图的顶点和边的信息建立图,并对其进行深度和广度遍历,输出遍历结果。
2.数据结构设计template <class ElemType>void AdjMatrixUndirGraph<ElemType>::InsertArc(int v1, int v2)// 操作结果:插入依附顶点v1和v2的边{if (v1 < 0 || v1 >= vexNum)throw Error("v1不合法!"); // 抛出异常if (v2 < 0 || v2 >= vexNum)throw Error("v2不合法!"); // 抛出异常if (v1 == v2)throw Error("v1不能等于v2!");// 抛出异常if (Matrix[v1][v2] == 0) { // 原无向图中没有边(v1, v2)arcNum++;Matrix[v1][v2] = 1;Matrix[v2][v1] = 1;}}template <class ElemType>void BFS(const AdjMatrixUndirGraph<ElemType> &g, int v, void (*Visit)(constElemType &))// 初始条件:存在图g// 操作结果:从顶点v出发进行广度优先搜索{LinkQueue<int> q;int u, w;ElemType e;g.SetTag(v, VISITED); // 作访问标志g.GetElem(v, e); // 取顶点v的数据元素值Visit(e); // 访问顶点vq.EnQueue(v); // 顶点v入队while (!q.Empty()) {q.DelQueue(u);for (w = g.FirstAdjVex(u); w != -1; w = g.NextAdjVex(u, w))if (g.GetTag(w) == UNVISITED){ // 对u尚未访问过的邻接顶点w 进行访问g.SetTag(w, VISITED);g.GetElem(w, e);Visit(e);q.EnQueue(w);}}}template <class ElemType>void DFS(const AdjMatrixUndirGraph<ElemType> &g, int v, void (*Visit)(const ElemType &))// 初始条件:存在图g// 操作结果:从顶点v出发进行深度优先搜索{ElemType e;g.SetTag(v, VISITED); // 设置顶点v已访问标志g.GetElem(v, e); // 取顶点v的数据元素值Visit(e); // 访问顶点vfor (int w = g.FirstAdjVex(v); w != -1; w = g.NextAdjVex(v, w)) if (g.GetTag(w) == UNVISITED)DFS(g, w , Visit); // 从v的尚未访问过的邻接顶点w开始进行深度优先搜索}3.算法设计#include "assistance.h" // 实用程序软件包#include "adj_matrix_undir_graph.h" // 无向图邻接矩阵#include "dfs.h" // 图的深度优先遍历#include "bfs.h" // 图的广度优先遍历int main(void){try // 用try封装可能出现异常的代码{int n=0, i, j, k, l;cout<<"请输入图的顶点个数:";cin>>n;if (n<=0||n>=26)throw Error("节点输入错误!");char a='A' ;char vexs[26];int m[26][26] ;for (i=0; i<n; i++){for (j=0; j<n; j++){m[i][j]=0;}}for(i=0; i<n; i++){vexs[i]=a;a++;}cout<<"输入边的两个顶点:(输入-1 -1结束)" ;cin>>k;cin>>l;if (k>=n||l>=n)throw Error("节点输入错误!");m[k][l]=1;m[l][k]=1;while (k!=-1||l!=-1){cout<<"输入边的两个顶点:(输入-1 -1结束)" ;cin>>k;cin>>l;if (k>=n||l>=n)throw Error("节点输入错误!");m[k][l]=1;m[l][k]=1;}AdjMatrixUndirGraph<char> g(vexs, n);AdjMatrixUndirGraph<char> g1(vexs, n);for(int u=0; u<n; u++){for(int v=0; v<n; v++){if( m[u][v]==1){ g.InsertArc(u,v);g1.InsertArc(u,v);} }}cout << "原有图:" << endl;g.Display(); // 显示图gcout << endl;system("PAUSE"); // 调用库函数system()int v=0;cout<<"请输入开始遍历的顶点"<<endl;cin>>v;if (v>=n)throw Error("节点输入错误!");cout << "深度优先遍历:";DFS<char>(g, v, Write<char>);// <char>用于确定函数模板参数cout << endl;system("PAUSE");cout << "广度优先遍历:";BFS(g1, v, Write<char>); // 对图g进行广度优先遍历cout << endl;}catch (Error err) // 捕捉并处理异常{err.Show(); // 显示异常信息}system("PAUSE"); // 调用库函数system()return 0; // 返回值0, 返回操作系统}4.测试与运行图的建立与遍历数据测试实验序号输入输出节点数相连的边开始遍历的点深度遍历广度遍历备注1 -1 / / / / 报错2 2 <1,3> / / / 报错3 3 <1,0>4 / / 报错4 2 <0.1> 0 A B A B /5 3 <0,1> <1,2> 0 A B C A B C /6 3 <0,2> <2,1> 2 C A B C A B /7 5 <0,2> <0,1><2,3> <1,4>2 C A B E D C A D B E /8 5 <0,1> <1,2><1,3> <1,4>0 A B C D E A B C D E /9 5 <0,1> <1,2><1,3> <1,4>3 D B A C E D B A C E /10 9 <0,1> <1,2><2,3> <3,7><3,4> <4,5><4,6> <7,8>A B C D EF G H IA B C D EH F G I/5.测试记录及收获给出测试中遇到的问题及解决的方法和过程。
数据结构图的建立和遍历
课程名称:数据结构开课实验室:计算中心204室2011年10 月日年级、专业、班学号姓名成绩实验项目名称图的建立和遍历指导教师教师评语教师签名:年月日一、实验内容和目的目的:撑握图的建立和遍历,熟悉图的建立和输出,还有两种遍历(深度和广度优先遍历)。
内容:编出图的程序,能够体图的性质、内容和算法。
二、上机实验环境计算中心204;操作系统:Microsoft Visual C++;软件平台:Microsoft Visual C++ 三、上机操作方法、步骤打开计算机进入WindowsXP→在桌面建立自己的工作目录→进入Microsoft Visual C++ 6.0→文件/新建/文件/C++ Source File/位置/命名→输入源程序→编译/组建→运行。
四、设计分析:图是一种复杂的非线性结构。
图结构在人工智能、计算机科学等领域有着广泛的运用。
学好它就得了解结点之间的关系是线性关系,除开始结点和终端结点外,每个结点只有一个直接前趋和直接后继。
在图结构中,对结点的前趋和后继个数都不加限制的,即结点之间的关系是任意的。
#include <stdio.h>#include<malloc.h>#define maxnode 30#define null 0#define m 20typedef struct st_arc{int adjvex;int weight;struct st_arc *nextarc;}arcnode;typedef struct{int vertex;struct st_arc *firstarc;}vernode;typedef vernode adjlist[maxnode];int queue[maxnode];void dfs(adjlist g,int k,int visited[]) //从顶点K出发深度优先搜索{arcnode *p;int w;visited[k]=1;printf("%d ",g[k].vertex);p=g[k].firstarc;while(p!=null){w=p->adjvex;if(visited[w]==0)dfs(g,w,visited);p=p->nextarc;}}void bfs(adjlist g,int k,int visited[]) //从顶点K出发广度优先搜索{int front=0,rear=1,w;arcnode *p;visited[k]=1; //访问初始顶点printf("%d ",k);queue[rear]=k; //初始顶点入队列while(front!=rear){front=(front+1)%m;w=queue[front]; //按访问次序依次出队列p=g[w].firstarc;while(p!=null){if(visited[p->adjvex]==0){visited[p->adjvex]=1;printf("%d ",p->adjvex);rear=(rear+1)%m;queue[rear]=p->adjvex;;}p=p->nextarc;}}}void trave_bfs(adjlist g,int n) //数组visited标志图中的顶点是否已被访问{int i,visited[maxnode];for(i=1;i<=n;i++)visited[i]=0;for(i=1;i<=n;i++)if(visited[i]==0)bfs(g,i,visited);}void trave_dfs(adjlist g,int n) //数组visited标志图中的顶点是否已被访问{int i,visited[maxnode];for(i=1;i<=n;i++)visited[i]=0;for(i=1;i<=n;i++)if(visited[i]==0)dfs(g,i,visited);}void print(adjlist g,int n){arcnode *q;int i;printf("输出的是所建立无向图的邻接表结构:\n");for(i=1;i<=n;i++){printf("\t%d\t",i);printf("%d->",g[i].vertex);q=g[i].firstarc;while(q!=null){printf("%d,",q->adjvex);printf("%d->",q->weight);q=q->nextarc;}printf("Null");printf("\n");}}void main(){arcnode *p,*q;adjlist g;int i,j,n,k,w,e;printf("请输入建立的无向图所包含的顶点总个数和总边数(用逗号隔开):");scanf("%d,%d",&n,&e);for(k=1;k<=n;k++){getchar();printf("\t输入每个顶点的信息,必须输入整数值:",k);scanf("%d",&g[k].vertex);g[k].firstarc=null; //对顺序存储部分初始化}for(k=1;k<=e;k++){printf("输入所有边的信息,(起始顶点,终止顶点和该边的权值 %d 如1,2,3):",k);scanf("%d,%d,%d",&i,&j,&w);q=(arcnode *)malloc(sizeof(arcnode));q->adjvex=j;q->weight=w;q->nextarc=g[i].firstarc;g[i].firstarc=q;p=(arcnode *)malloc(sizeof(arcnode));p->adjvex=i;p->weight=w;p->nextarc=g[j].firstarc;g[j].firstarc=p;}print(g,n);printf("\n");printf("输出深度优先搜索遍历:");trave_dfs(g,n);printf("\n");printf("输出广度优先搜索遍历:");trave_bfs(g,n);printf("\n");}五、源程序与运行结果:五、上机实践收获和体会:经过学习和上机实践,我基本了解和撑握图的基本概念和两种常用的存储结构,对图的遍历、最小生成树、最短路弃、拓扑排序等理解,撑握图的有关术语和存储表示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验七图的创建与遍历
实验目的:
通过上机实验进一步掌握图的存储结构及基本操作的实现。
实验内容与要求:
要求:
⑴能根据输入的顶点、边/弧的信息建立图;
⑵实现图中顶点、边/弧的插入、删除;
⑶实现对该图的深度优先遍历;
⑷实现对该图的广度优先遍历。
备注:单号基于邻接矩阵,双号基于邻接表存储结构实现上述操作。
算法设计:
#include <iostream>
#include <malloc.h>
#define INFINITY 32767
#define MAX_VEX 20 //最大顶点个数
#define QUEUE_SIZE (MAX_VEX+1) //队列长度
using namespace std;
bool *visited; //访问标志数组
//图的邻接矩阵存储结构
typedef struct{
char *vexs; //顶点向量
int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
}Graph; //队列类
class Queue{
public:
void InitQueue()
{
base=(int
*)malloc(QUEUE_SIZE*sizeof(int));
front=rear=0;
.
}
void EnQueue(int e)
{
base[rear]=e;
rear=(rear+1)%QUEUE_SIZE;
}
void DeQueue(int &e)
{
e=base[front];
front=(front+1)%QUEUE_SIZE;
}
public:
int *base;
int front;
int rear;
}; //图G中查找元素c的位置
int Locate(Graph G,char c)
{
for(int i=0;i<G.vexnum;i++)
if(G.vexs[i]==c) return i;
return -1;
} void CreateUDN(Graph &G) //创建无向网
{
int i,j,w,s1,s2;
char a,b,temp;
printf("输入顶点数和弧数:");
scanf("%d%d",&G.vexnum,&G.arcnum) ;
temp=getchar(); //接收回车
G.vexs=(char
*)malloc(G.vexnum*sizeof(char)); //分配顶点数目
printf("输入%d个顶点.\n",G.vexnum);
for(i=0;i<G.vexnum;i++) //初始化顶点
{
printf("输入顶点%d:",i);
scanf("%c",&G.vexs[i]);
temp=getchar(); //接收回车}
for(i=0;i<G.vexnum;i++) //初始化邻接矩阵
for(j=0;j<G.vexnum;j++)
G.arcs[i][j]=INFINITY;
printf("输入%d条弧.\n",G.arcnum);
for(i=0;i<G.arcnum;i++)//初始化弧
{
printf("输入弧%d:",i);
scanf("%c %c %d",&a,&b,&w); //输入一条边依附的顶点和权值
temp=getchar(); //接收回车
s1=Locate(G,a);
s2=Locate(G,b);
G.arcs[s1][s2]=G.arcs[s2][s1]=w;
}
}
int FirstVex(Graph G,int k) //图G中顶点k的第一个邻接顶点
{
if(k>=0 && k<G.vexnum) //k 合理
{
for(int i=0;i<G.vexnum;i++)
if(G.arcs[k][i]!=INFINITY) return i;
}
return -1;
} //图G中顶点i的第j个邻接顶点的下一个邻接顶点
int NextVex(Graph G,int i,int j)
{
if(i>=0 && i<G.vexnum && j>=0 && j<G.vexnum) //i,j合理
{
for(int
k=j+1;k<G.vexnum;k++)
if(G.arcs[i][k]!=INFINITY) return k;
}
return -1;
}
void DFS(Graph G,int k) //深度优先
遍历
{
int i;
if(k==-1) //第一次执行DFS时,k 为-1
{
for(i=0;i<G.vexnum;i++)
if(!visited[i]) DFS(G,i); //对尚未访问的顶点调用DFS
}
else
{
visited[k]=true;
printf("%c ",G.vexs[k]); //访问第k个顶点
for(i=FirstVex(G,k);i>=0;i=NextVex(G,k, i))
if(!visited[i]) DFS(G,i); //对k的尚未访问的邻接顶点i递归调用DFS
}
} void BFS(Graph G) //广度优先遍历{
int k;
Queue Q; //辅助队列Q
Q.InitQueue();
for(int i=0;i<G.vexnum;i++)
if(!visited[i]) //i尚未访问
{
visited[i]=true;
printf("%c ",G.vexs[i]);
Q.EnQueue(i); //i入列
while(Q.front!=Q.rear)
{
Q.DeQueue(k); //队头元素出列并置为k
for(int
w=FirstVex(G,k);w>=0;w=NextVex(G,k, w))
if(!visited[w]) //w 为k的尚未访问的邻接顶点
{
visited[w]=true;
printf("%c ",G.vexs[w]);
Q.EnQueue(w);
}
}
}
}
void main()
{
int i;
Graph G;
CreateUDN(G);
visited=(bool
*)malloc(G.vexnum*sizeof(bool));
printf("\n广度优先遍历: ");
for(i=0;i<G.vexnum;i++)
visited[i]=false;
DFS(G,-1);
printf("\n深度优先遍历: ");
for(i=0;i<G.vexnum;i++)
visited[i]=false;
BFS(G);
printf("\n");
}
实验结果:
欢迎下载,谢谢观看!资料仅供参考学习。