四 图的基本操作
来源:互联网 发布:360抢购软件神器 编辑:程序博客网 时间:2024/06/05 16:49
实验四
一、实验目的
1、掌握图的存储思想及其存储实现。
2、掌握图的深度、广度优先遍历算法思想及其程序实现。
3、掌握图的常见应用算法的思想及其程序实现。
二、实验仪器及环境:
PC计算机;windows XP操作系统、Visual C++6.0
三、实验内容及结果(按照具体实验题目,按照如下格式书写)
1、键盘输入数据,建立一个有向图的邻接表。
2、输出该邻接表。
3、在有向图的邻接表的基础上计算各顶点的度,并输出。
4、以有向图的邻接表为基础实现输出它的拓扑排序序列。
5、采用邻接表存储实现有向图的深度优先递归遍历。
*6、采用邻接表存储实现有向图的广度优先遍历(利用队列实现)。
7、编写一个主函数,调试上述算法。
#include <iostream>#include <stdio.h>#include <stdlib.h>using namespace std;#define MAXVNUM 10 //顶点最大个数#define MAX 20typedef struct Node{ int adjvex;struct Node *nextarc; int weight; //边的权}ArcNode; //表结点 #define VertexType int //顶点元素类型typedef struct{ int outdegree,indegree;//顶点的度,入度int vetex;VertexType data;ArcNode *firstarc;}VNode/*头结点*/; typedef struct{ VNode vertices[MAXVNUM];int vexnum,arcnum;//顶点的实际数,边的实际数 }ALGraph; void CreatAdjList( ALGraph &G ) //建立有向图的邻接表存储结构 { int n,m=0,i,j; cout<<"输入顶点个数"<<endl; scanf("%d",&n); //输入顶点个数 cout<<"输入顶点信息\n"; for ( i=1;i<=n;i++) //输入顶点信息 { scanf("%d",&G.vertices[i].vetex); G.vertices[i].firstarc=NULL; } cout<<"输入弧(0 0表示输入停止)\n"; scanf("%d%d",&i,&j); //输入弧while(i!=0 && j!=0) //两顶点之一为0表示结{ ArcNode *p=(ArcNode*)malloc(sizeof(ArcNode)); p->adjvex=j; p->nextarc=G.vertices[i].firstarc; G.vertices[i]. firstarc=p; m++; //弧的个数加1 cout<<"输入弧(0 0表示输入停止)\n"; scanf("%d%d",&i,&j); } G.vexnum=n; G.arcnum=m; ArcNode *p=(ArcNode*)malloc(sizeof(ArcNode)); for(i=1;i<=G.vexnum;i++) ///初始化入度出度 { G.vertices[i].indegree=G.vertices[i].outdegree=0; } for(i=1;i<=G.vexnum;i++) ///计算入度出度 { p=G.vertices[i].firstarc; while(p!=NULL) { G.vertices[p->adjvex].indegree++; G.vertices[i].outdegree++; p=p->nextarc; } }}int visited[MAXVNUM] ;// 访问标志数组 int GraphFirstAdj(ALGraph g,int v)//得到v的第一个邻结点{ if(g.vertices[v].firstarc!=NULL) return g.vertices[v].firstarc->adjvex; else return 0;}int GraphNextAdj(ALGraph g,int v,int w)//返回v的(相对于w的)下一个邻接点,若w是v的最后一个邻接点,则返回0{ ArcNode *p= (ArcNode*)malloc(sizeof(ArcNode)); p=g.vertices[v].firstarc; while(p) { if(p->adjvex==w&&p->nextarc!=NULL) return p->nextarc->adjvex; p=p->nextarc; } return 0;}void DFS(ALGraph G, int v) { // 从 顶点v出发递归地深度优先遍历图 G cout<<G.vertices[v].vetex<<endl;visited[v]=1; // 访问v顶点(输出v) for(int w=GraphFirstAdj(G, v); w ; w=GraphNextAdj(G,v,w)) if(!visited[w]) DFS(G, w); } void DFSTraverse(ALGraph G) //深度优先遍历图G { int v; for(v=1;v<G.vexnum;v++) visited[v]=0; // 初始访问数组置未访问标志 for(v=1;v<G.vexnum;v++) if(!visited[v])DFS(G,v); // 对未访问过的顶点调用 DFS }typedef int ElemType; typedef struct ///定义队列{ ElemType base[MAX]; int front,rear;///队头,队尾}SqQueue; SqQueue SqQueueInit()///初始化队列{ SqQueue Q; Q.front=Q.rear=0; return Q;} int SqQueueEmpty(SqQueue Q)///判断队列是否为空{ if (Q.front==Q.rear) return 1; else return 0;} SqQueue SqQueueIn(SqQueue Q,ElemType x)///入队{ if ((Q.rear+1)%MAX==Q.front) { printf("队满\n"); return Q; } ///队满,退出运行 Q.base[Q.rear]=x; Q.rear=(Q.rear+1)%MAX; return Q;} ElemType SqQueueGetTop(SqQueue Q)///若队非空返回对头元素的值{ return (Q.base[Q.front]);} SqQueue SqQueueOut(SqQueue Q,ElemType &x)///出队{ if(Q.front==Q.rear) { printf("队空\n"); return Q; } ///队已空,退出运行 x=Q.base[Q.front]; Q.front=(Q.front+1)%MAX; return Q;} void BFSTraverse(ALGraph g)//图的bfs遍历{ for(int i=1;i<=g.vexnum;i++)visited[i]=0;// 初始访问数组 SqQueue q=SqQueueInit(); for(int i=1;i<=g.vexnum;i++) { if(!visited[i]) { q=SqQueueIn(q,i); visited[i]=1; cout<<g.vertices[i].vetex<<endl; while(!SqQueueEmpty(q)) { int v = SqQueueGetTop(q);//对头元素出队列并置为v q=SqQueueOut(q,v); for(int w=GraphFirstAdj(g,v);w!=0;w=GraphNextAdj(g,v,w))//遍历v的邻结点 { if(!visited[w]) { q=SqQueueIn(q,w);//v的尚未访问的邻接顶点w入队列Q visited[w]=1; cout<<g.vertices[w].vetex<<endl; } } } } }}void PrintA(ALGraph G) ///输出邻接表{ int i; ArcNode *p; printf("\n***输出邻接表:***\n"); for(i=1;i<=G.vexnum;i++) { p=G.vertices[i].firstarc; printf("%d",G.vertices[i].vetex); while(p!=NULL) { printf(" -> %d",p->adjvex); p=p->nextarc; } printf("\n"); } printf("\n");}void PrintDegree(ALGraph A) ///顶点的度{ int i; for(i=1;i<=A.vexnum;i++) { printf("顶点 %2d 的入度是: %2d 出度是: %2d \n",i,A.vertices[i].indegree,A.vertices[i].outdegree); } printf("\n");}void PrintTuopu(ALGraph A) ///计算拓扑序列{ int t[MAXVNUM][2]; int flag=1,i,j; ArcNode *p=NULL; memset(t,0,sizeof(t)); if(p==NULL)printf("***输出拓扑序列***\n"); for(i=1;i<=A.vexnum;i++) { t[i][0]=A.vertices[i].indegree; t[i][1]=A.vertices[i].outdegree; } for(i=1;i<=A.vexnum&&flag==1;i++) { flag==0; for(j=1;j<=A.vexnum;j++) { if(t[j][0]==0) { t[j][0]=-1; flag==1; break; } } if(flag==1) { p=A.vertices[j].firstarc; printf("%d ",A.vertices[j].vetex); while(p!=NULL) { t[p->adjvex][0]--; p=p->nextarc; } } else { printf("此图有环\n"); return; } } printf("\n");}int main(){ ALGraph G; CreatAdjList(G); PrintA(G); PrintDegree(G); cout<<"\n深度优先遍历\n"; DFSTraverse(G); cout<<"\n广度优先遍历\n"; BFSTraverse(G); printf("拓扑序\n"); PrintTuopu(G); return 0;}
四、实验心得体会:(包括遇到的问题及解决办法)
图的算法对于多对多的关系的存储和处理都很实用,在今后的学习生活中可能会经常遇到,所以要加强对于此部分的理解。
阅读全文
0 0
- 四 图的基本操作
- ADO的基本操作(四)修改
- 四 运算符的基本操作B
- 四、对数据库的基本操作
- OpenCV(四)图像的基本操作
- Swift字符串的基本操作(四)
- 实验四 队列的基本操作
- 数组基本操作(四)
- opencv基本操作四
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- *图的基本操作*
- 图的基本操作
- linux运维面试题
- python的with语句和上下文管理器初窥
- Eloquent JavaScript 笔记 十二:Javascript and the Browser
- activeMQ学习笔记 -- day02安装测试
- 377. Combination Sum IV
- 四 图的基本操作
- d3画过渡动画
- virtualbox安装Centos
- 五 查找的有关操作
- android之fragment征程
- iOS创建公有CocoaPods库
- html的单选框与复选框
- Java 监听器
- warning: #61-D: integer operation result is out of range