#include<cstdio> #include<cstring> #include<queue> #include<iostream> #include<cstdlib> using namespace std; #define MaxInt 32767 #define MVNum 100 bool visited[MaxInt]; typedef int VerTexType; typedef int ArcType,OtherInfo; typedef struct ArcNode{//边 int adjvex;//顶点序号 struct ArcNode *nextarc;//下一条边的指针 OtherInfo info;// }ArcNode; typedef struct VNode{//顶点 VerTexType data; ArcNode *firstarc; }VNode,AdjList[MVNum]; typedef struct{ AdjList vertices; int vexnum,arcnum; }ALGraph; int LocateVex(ALGraph G,int u){//图G存在,u和G中顶点有相同特征。若G中存在顶点u,则返回该顶点在图中的位置;否则返回其他信息。 for(int i=0;i<G.vexnum;i++){ if(G.vertices[i].data==u){ return i; } } return -1; } void CreateGraph(ALGraph &G){//V是图的顶点集,VR是图中弧的集合。按V和R的定义构造图G。 cout<<"请输入顶点数,边数:"<<" "; cin>>G.vexnum>>G.arcnum; cout<<" 请输入每个顶点的值:"<<" "; for(int i=0;i<G.vexnum;i++){ cin>>G.vertices[i].data; G.vertices[i].firstarc=NULL; } cout<<"输入边:"<<" "; for(int k=0;k<G.arcnum;k++){ int v1,v2; cin>>v1>>v2; int i=LocateVex(G,v1); int j=LocateVex(G,v2); ArcNode *p1,*p2; p1=new ArcNode; p1->adjvex=j; p1->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=p1; p2=new ArcNode; p2->adjvex=i; p2->nextarc=G.vertices[j].firstarc; G.vertices[j].firstarc=p2; } return; } void DestroyGraph(ALGraph &G){//图G存在。销毁图G。 ArcNode *p, *q; G.vexnum = 0; G.arcnum = 0; for( int i = 0; i < G.vexnum; i++ ){ p = G.vertices[i].firstarc; while( p!=NULL ){ q = p->nextarc; free( p ); p = q; } } return; } int GetVex(ALGraph G,int v){//图G存在,v是G中某个顶点。返回v的值。 for(int i=0;i<G.vexnum;i++){ if(i==v){ return G.vertices[i].data; } } return 0; } void PutVex( ALGraph &G, VerTexType v, VerTexType value){//图G存在,v是G中某个顶点。对v赋值value。 for(int i=0;i<G.vexnum;i++){ if(i==v){ G.vertices[i].data=value; } } return; } int FirstAdjVex( ALGraph G, VerTexType v ){//图G存在,v是G中某个顶点。返回v的第一个邻接顶点,若v在G中没有邻接顶点,则返回“空”。 ArcNode *p; int v1; v1 = LocateVex( G,v ); p = G.vertices[v1].firstarc; if( p!=NULL ) return p->adjvex; else return -1; } int NextAdjVex(ALGraph G, VerTexType v, VerTexType w){//图G存在,v是G中某个顶点,w是v的邻接顶点。 返回v的(相对于w的)下一个邻接顶点。若w是v的最后一个邻接顶点,则返回“空”。 ArcNode *p; int v1, w1; v1 = LocateVex( G, v ); //v1为顶点v在图G中的序号 w1 = LocateVex( G, w ); //w1为顶点w在图G中的序号 p = G.vertices[v1].firstarc; while( p!=NULL && p->adjvex != w1 ) //指针p不空且所指针表结点不是w p = p->nextarc; if( p==NULL || p->nextarc==NULL ) //没找到w或w是最后一个邻接顶点 return -1; else return p->nextarc->adjvex; } void InsertVex(ALGraph &G, VerTexType v ){//图G存在,u和G中顶点有相同特征。在图G中增添新顶点v. G.vertices[G.vexnum].data = v; //构造新顶点向量 G.vertices[G.vexnum].firstarc = NULL; G.vexnum++; //图G的顶点数加1 return; } void DeleteVex( ALGraph &G, VerTexType v ){//图G存在,v是G中某个顶点。删除G中顶点v及其相关的弧。 int i, j; ArcNode *p, *q; j = LocateVex( G, v ); //j是定点v的序号 if( j < 0 ){ //v不是图G的顶点 return; } p = G.vertices[j].firstarc; //删除以v为出度的弧或边 while( p ){ q = p; p = p->nextarc; free( q ); G.arcnum--; //弧或边数减1 } G.arcnum--; //顶点数减1 for( i = j; i < G.vexnum; i++ ){//顶点v后面的顶点前移 G.vertices[i] = G.vertices[i+1]; } for( i = 0; i < G.vexnum; i++ ){//删除以v为入度的弧或边且必要是修改表结点的顶点位置 p = G.vertices[i].firstarc; //指向第1条弧或边 while( p!=NULL ){//有弧 if( p->adjvex == j ){ if( p == G.vertices[i].firstarc ){//待删结点是第1个结点 G.vertices[i].firstarc = p->nextarc; free( p ); p = G.vertices[i].firstarc; }else{ q->nextarc = p->nextarc; free( p ); p = p->nextarc; } }else{ if( p->adjvex > j ){ p->adjvex--; //修改表结点的顶点位置值 } q = p; p = p->nextarc; } } } return; } void InsertArc( ALGraph &G, VerTexType v, VerTexType w){//图G存在,v和w是G中两个顶点。在G中增添<v,w>,若G是无向图,则还增添对称弧<w,v>。 ArcNode *p; int w1, i, j; i = LocateVex( G, v); //弧尾或边的序号 j = LocateVex( G, w ); //弧头或边的序号 if( i < 0 || j < 0 ){ return; } G.arcnum++; p = new ArcNode; p->adjvex = j; p->nextarc = G.vertices[i].firstarc; //插在表头 G.vertices[i].firstarc = p; //无向,生产另一个表结点 return; } void DeleteArc(ALGraph &G, VerTexType v, VerTexType w){//图G存在,v和w是G中两个顶点。在G中删除<v,w>,若G是无向图,则还删除对称弧<w,v>。 ArcNode *p, *q; int i, j; i = LocateVex( G, v ); //i是定点(弧尾)的序号 j = LocateVex( G, w ); //j是定点(弧头)的序号 if( i < 0 || j < 0 || i == j ){ return; } p = G.vertices[i].firstarc; //p指向顶点v的第一条弧尾 while( p && p->adjvex != j ){ //p不空且所指之弧不是待删除<v,w> q = p;//p指向下一条弧 p = p->nextarc; } if( p && p->adjvex == j ){ //找到弧<v,w> if( p == G.vertices[i].firstarc ){//p是指第1条弧 G.vertices[i].firstarc = p->nextarc; //指向下一条弧 }else{ q->nextarc = p->nextarc; //指向下一条弧 } free( p ); //弧或边数减1 G.arcnum--; } return; } void DFSTraverse(ALGraph G,VerTexType v){//图G存在。对图进行深度优先遍历,在遍历过程中对每个顶点访问一次。 cout<<v<<" "; visited[v]=true; ArcNode *p; p=new ArcNode; int vi=LocateVex(G,v); p=G.vertices[vi].firstarc; while(p!=NULL){ int w=G.vertices[p->adjvex].data; if(visited[w]==0){ DFSTraverse(G,w); } p=p->nextarc; } return; } void BFSTraverse(ALGraph G,VerTexType v){//图G存在。对图进行广度优先遍历,在遍历过程中对每个顶点访问一次。 cout<<v<<" "; visited[v]=true; queue<int>Q; Q.push(v); while(Q.empty()==0){ int u=Q.front(); Q.pop(); for(int w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,G.vertices[w].data)){ int x=G.vertices[w].data; if(visited[x]==0){ cout<<x<<" "; visited[x]=true; Q.push(x); } } } return; } int VertexDegree(ALGraph &G, VerTexType v){ ArcNode *p; p=new ArcNode; for(int i=0;i<G.vexnum;i++){ if(v==G.vertices[i].data){ p=G.vertices[i].firstarc; break; } } int num=0; while(p!=NULL){ num++; p=p->nextarc; } return num; } int main(){ ALGraph G; int v; cout<<"18软件轨道信号一班石启隆 "; CreateGraph(G); cout<<"对图进行广度优先遍历,输入历遍起点:"<<" "; cin>>v; memset(visited,0,sizeof(visited)); BFSTraverse(G,v); cout<<" 对图进行深度优先遍历,输入历遍起点:"<<" "; cin>>v; memset(visited,0,sizeof(visited)); DFSTraverse(G,v); cout<<" 求一个结点的度,输入一个结点: "; cin>>v; cout<<"该结点的度为: "<<VertexDegree(G,v)<<" "; return 0; }