标签:
1.邻接表的简介:
#include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <queue> using namespace std; #define N 200 typedef enum GraphKind {DG,DN,UDG,UDN}; typedef char VertexType[20]; typedef struct ArcNode { int adjvex;//该弧指向的顶点的位置 int *info; //该弧的相关信息 ArcNode *nextarc;//指向下一条弧的指针 }; typedef struct { VertexType data;//顶点信息 ArcNode *firstarc; //指向第一条依附该顶点的弧的指针 } VNode,AdjList[N]; typedef struct ALGraph { AdjList vertices; int vexnum,arcnum;//弧的当前顶点数和弧数 int kind;//图的种类 }; //1.顶点的位置: int LocateVex(ALGraph g,VertexType u) { int i; for(i=0; i<g.vexnum; i++) { if(strcmp(g.vertices[i].data,u)==0) return i; } return -1; } //2.采用邻接表存储结构,构造没有相关信息的图G //(用一个函数构造4种图) void CreateGraph(ALGraph &G) { int i, j, k; int w; //权值 VertexType va , vb ; ArcNode *p; cout << "请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3):" << endl; cin >> G.kind; cout << "请输入图的顶点数,边数: " << endl; cin >> G.vexnum >> G.arcnum; cout << "请输入" << G.vexnum << "个顶点的值(" << "1" << "个字符)每个用空格隔开:" << endl; for( i = 0; i <G.vexnum; i++ ) //构造顶点向量 { cin >> G.vertices[i].data; G.vertices[i].firstarc = NULL; } if( G.kind == 1 || G.kind == 3 ) //网 cout << "请顺序输入每条弧(边)的权值,弧尾和弧头(以空格作为间隔):" << endl; else //图 cout << "请顺序输入每条弧边的弧尾和弧头(以空格作为间隔):" << endl; for( k = 0; k < G.arcnum; k++ ) //构造表结点链表 { if( G.kind == 1 || G.kind == 3 ) //网 cin >> w >> va >> vb; else //图 cin >> va >> vb; i = LocateVex( G, va ); //弧头 j = LocateVex( G, vb ); //弧尾 p = ( ArcNode * )malloc( sizeof( ArcNode ) ); p->adjvex = j; if( G.kind == 1 || G.kind == 3 ) { p->info = ( int * )malloc( sizeof( int ) ); *( p->info ) = w; } else p->info = NULL; p->nextarc = G.vertices[i].firstarc; //插在表头 G.vertices[i].firstarc = p; if( G.kind >= 2 ) //无向图或网,产生第二个表结点 { p = ( ArcNode* )malloc( sizeof( ArcNode ) ); p->adjvex = i; if( G.kind == 3 ) //无向图 { p->info = ( int * )malloc( sizeof( int ) ); *( p->info ) = w; } else p->info = NULL; //无向图 p->nextarc = G.vertices[j].firstarc; //插在表头 G.vertices[j].firstarc = p; } } } void Prt(ALGraph G) { int i; printf("vexnum :%d, arcnum :%d.\n\n",G.vexnum,G.arcnum); printf("VexList:\n"); for(i = 0; i < G.vexnum; i++){ printf(" v(%d):%s|",i,G.vertices[i].data); ArcNode *p = G.vertices[i].firstarc; while(p){ printf("->%d",p->adjvex); p = p->nextarc; } printf("\n"); } } void find(ALGraph &g,VertexType a,VertexType b) { int i,j; i=LocateVex(g,a); j=LocateVex(g,b); ArcNode *p,*q1,*q2; if(g.kind>=2) { p=g.vertices[i].firstarc; int flag=0; while(p) { if(p->adjvex==j) { flag=1; break; } p=p->nextarc; } if(flag==1) { cout<<"YES"<<endl; if(g.kind%2==1) cout<<*(p->info)<<endl; } else { cout<<"NO"<<endl; } } else { q1=g.vertices[i].firstarc; int flag1=0,flag2=0; while(q1) { if(q1->adjvex==j) { flag1=1; break; } q1=q1->nextarc; } q2=g.vertices[j].firstarc; while(q2) { if(q2->adjvex==i) { flag2=1; break; } q2=q2->nextarc; } if(flag1==1) { cout<<a<<"->"<<b<<endl; if(g.kind%2==1) cout<<*(q1->info)<<endl; } else if(flag2==1) { cout<<b<<"->"<<a<<endl; if(g.kind%2==1) cout<<*(q2->info)<<endl; } else { cout<<"NO"<<endl; } } } void degree(ALGraph &g,VertexType a) { int i,j,k; ArcNode *p,*q; if(g.kind>1) { int sum=0; i=LocateVex(g,a); p=g.vertices[i].firstarc; while(p) { sum++; p=p->nextarc; } cout<<a<<"的度为:"<<sum<<endl; } else { int sum1=0,sum2=0; i=LocateVex(g,a); p=g.vertices[i].firstarc; while(p) { sum1++; p=p->nextarc; } for(j=0; j<g.vexnum; j++) { if(j!=i) { q=g.vertices[j].firstarc; while(q) { if(q->adjvex==i) { sum2++; } q=q->nextarc; } } } cout<<a<<"的度为:"<<(sum1+sum2)<<endl; } } bool vis[N]; //返回v的第一个邻接顶点的序号,若图中无邻接顶点,返回-1 int FirstAdjVex(ALGraph G,VertexType v){ int i = LocateVex(G,v); ArcNode *p = G.vertices[i].firstarc; if(p){ return p->adjvex; } else{ return -1; } } //返回v的(相对于w的)下一个邻接顶点的序号。若w是v的最后一个邻接顶点,则返回-1 int NextAdjVex(ALGraph G,VertexType v,VertexType w){ int i = LocateVex(G,v); int j = LocateVex(G,w); ArcNode *p = G.vertices[i].firstarc; while(p){ if(p->adjvex == j) break; p = p->nextarc; } if(!p || !p->nextarc){ //没找到w或w是最后一个邻接点 return -1; } else{ return (p->nextarc)->adjvex; } } //深度优先搜索 void DFS(ALGraph G,int v){ int w; vis[v] = true; printf("%s ",G.vertices[v].data); //访问第v个顶点 w = FirstAdjVex(G,G.vertices[v].data); while(w >= 0){ if(!vis[w]){ DFS(G,w); } w = NextAdjVex(G,G.vertices[v].data,G.vertices[w].data); } } //对图做深度优先遍历 void DFSTraverse(ALGraph G){ int v; memset(vis,false,sizeof(vis)); for(v = 0; v < G.vexnum; v++){ if(!vis[v]){ DFS(G,v);//对尚未访问的顶点调用DFS } } printf("\n"); } //对图做广度优先搜索 void BFSTraverse(ALGraph G) { int v,u,w; queue<int>q; memset(vis,false,sizeof(vis)); for(v = 0; v < G.vexnum; v++){ //如果是连通图,v = 0就遍历全图 if(!vis[v]){ vis[v] = true; printf("%s ",G.vertices[v].data); } q.push(v); while(!q.empty()){ u=q.front(); q.pop(); //队头元素出队,并置为u w = FirstAdjVex(G,G.vertices[u].data); while(w >= 0){ if(!vis[w]){ vis[w] = true; printf("%s ",G.vertices[w].data); q.push(w);//入队 } w = NextAdjVex(G,G.vertices[u].data,G.vertices[w].data); } } } printf("\n"); } int main() { ALGraph g; CreateGraph(g); printf("输出邻接表:\n"); Prt(g); VertexType a,b; printf("输入两个顶点:\n"); cin>>a>>b; printf("输出顶点之间是否存在边:\n"); find(g,a,b); printf("输入一个顶点:\n"); cin>>a; printf("输出该点的度:\n"); degree(g,a); printf("深度优先搜索遍历:\n"); DFSTraverse(g); printf("广度优先搜索遍历:\n"); BFSTraverse(g); return 0; }
标签:
原文地址:http://www.cnblogs.com/famousli/p/4242729.html