邻接表的部分操作和BFS遍历
有向图可以指向本身,则边表的长度可以和顶点表长度相同
for(i=0;i<G.VerNum;i++) { ArcNode *p=G.Ver[i].first; for(j=0;j<G.VerNum;j++) //有向图顶点可以指向自己 . . . }
创造图时,对于边表采用头插法
ArcNode *arcnode=(ArcNode*)malloc(sizeof(ArcNode)); arcnode->adjvex=x; arcnode->next=G.Ver[i].first; G.Ver[i].first=arcnode;
对于图的基本函数:FirstNeighbor(G,x)和NextNeighbor(G,x,y)
FirstNeighbor(G,x):返回与x顶点相邻的第一个顶点索引号,对表格来说,返回1
NextNeighbor(G,x,y):返回与x顶点相邻,除了y顶点外的下一个顶点的索引号,对表格来说,返回2
0 | 1 | 2 |
x | y | z |
int ArrNum(Graph G,int ver) { for(int i=0;i<G.VerNum;i++) if(G.Ver[i].data==ver) return i; return -1; } int FirstNeighbor(Graph G,int ver) { int x=ArrNum(G,ver); if(x!=-1 && G.Ver[x].first!=NULL) return ArrNum(G,G.Ver[x].first->adjvex); return -1; } int NextNeighbor(Graph G,int ver,int w) { int x=ArrNum(G,ver); ArcNode *arcnode=G.Ver[x].first; while(arcnode!=NULL && arcnode->adjvex!=w) arcnode=arcnode->next; if(arcnode->next!=NULL) return ArrNum(G,arcnode->next->adjvex); return -1; }
广度优先遍历:
1、BFSTraverse(Graph G)
对于图这种数据结构,可能会存在好几个连通分量,对G2而言,一次广度优先无法将图中所有顶点都遍历一遍
void BFSTraverse(Graph G) { for(int i=0;i<G.VerNum;i++) visited[i]=false; for(int i=0;i<G.VerNum;i++) if(!visited[i]) BFS(G,i); }
2、BFS(Graph G,int v)
入队的是对应顶点的第一个边表结点,手动模拟一边就清楚了。
bool visited[MaxSize]; void BFS(Graph G,int v) { printf("%d ", G.Ver[v].data); visited[v] = true; Queue Q; InitQueue(Q); EnQueue(Q, G.Ver[v].first); while (!isEmpty(Q)) { ArcNode* arcnode; DeQueue(Q, arcnode); while (arcnode != NULL) { int i = ArrNum(G,arcnode->adjvex); if (!visited[i]) { printf("%d ", G.Ver[i].data); visited[i] = true; EnQueue(Q, G.Ver[i].first); } arcnode = arcnode->next; } } }
完整代码:
#include <stdio.h> #include <stdlib.h> #define MaxSize 20 typedef struct ArcNode{ //边表结点 struct ArcNode *next; int adjvex; }ArcNode; typedef struct VNode{ //主表结点 int data; ArcNode *first; }VNode,AdjList[MaxSize]; typedef struct{ //图 AdjList Ver; int VerNum,EdgeNum; }Graph; typedef struct{ ArcNode *data[MaxSize]; int front,rear; }Queue; void InitQueue(Queue &Q) { Q.front=Q.rear=0; } bool isEmpty(Queue Q) { if(Q.rear==Q.front) return true; return false; } bool isFull(Queue Q) { if((Q.rear+1)%MaxSize==Q.front) return true; return false; } bool EnQueue(Queue &Q,ArcNode *arcnode) { if(isFull(Q)) return false; Q.data[Q.rear]=arcnode; Q.rear=(Q.rear+1)%MaxSize; return true; } bool DeQueue(Queue &Q,ArcNode* &arcnode) { if(isEmpty(Q)) return false; arcnode=Q.data[Q.front]; Q.front=(Q.front+1)%MaxSize; return true; } void CreateGraph(Graph &G) { int x,i,j; printf("请输入顶点元素:\n"); for(i=0;i<MaxSize;i++) { scanf("%d",&x); if(x==-1) break; G.Ver[i].data=x; G.Ver[i].first=NULL; G.VerNum++; } printf("请输入边表:\n"); for(i=0;i<G.VerNum;i++) { ArcNode *p=G.Ver[i].first; for(j=0;j<G.VerNum;j++) //有向图顶点可以指向自己 { scanf("%d",&x); if(x==-1) break; ArcNode *arcnode=(ArcNode*)malloc(sizeof(ArcNode)); arcnode->adjvex=x; arcnode->next=G.Ver[i].first; G.Ver[i].first=arcnode; G.EdgeNum++; } } } void DisplayGraph(Graph G) { int i,j; printf("顶点元素为:\n"); for(i=0;i<G.VerNum;i++) G.Ver[i].data; printf("边为:\n"); for(i=0;i<G.VerNum;i++) { printf("%d->",G.Ver[i].data); ArcNode *arc=G.Ver[i].first; while(arc!=NULL) { printf("%d ",arc->adjvex); arc=arc->next; } printf("\n"); } printf("顶点元素共有%d个\n",G.VerNum); printf("边有%d条\n",G.EdgeNum); } int ArrNum(Graph G,int ver) { for(int i=0;i<G.VerNum;i++) if(G.Ver[i].data==ver) return i; return -1; } int FirstNeighbor(Graph G,int ver) { int x=ArrNum(G,ver); if(x!=-1 && G.Ver[x].first!=NULL) return ArrNum(G,G.Ver[x].first->adjvex); return -1; } int NextNeighbor(Graph G,int ver,int w) { int x=ArrNum(G,ver); ArcNode *arcnode=G.Ver[x].first; while(arcnode!=NULL && arcnode->adjvex!=w) arcnode=arcnode->next; if(arcnode->next!=NULL) return ArrNum(G,arcnode->next->adjvex); return -1; } bool visited[MaxSize]; void BFS(Graph G,int v) { printf("%d ", G.Ver[v].data); visited[v] = true; Queue Q; InitQueue(Q); EnQueue(Q, G.Ver[v].first); while (!isEmpty(Q)) { ArcNode* arcnode; DeQueue(Q, arcnode); while (arcnode != NULL) { int i = ArrNum(G,arcnode->adjvex); if (!visited[i]) { printf("%d ", G.Ver[i].data); visited[i] = true; EnQueue(Q, G.Ver[i].first); } arcnode = arcnode->next; } } } void BFSTraverse(Graph G) { for(int i=0;i<G.VerNum;i++) visited[i]=false; for(int i=0;i<G.VerNum;i++) if(!visited[i]) BFS(G,i); } int main() { Graph G; CreateGraph(G); DisplayGraph(G); BFSTraverse(G); return 0; }