一、 常见图存储方式有邻接矩阵存储方法和邻接表存储方法,在此采用邻接表存储方法,包括一个顺序表(顶点信息)和一组链表(边信息):
typedef struct ArcNode{ int adjvex; //the number of the destination of this links struct ArcNode *next; //the next link of this node /*int *weight; //the weight of the link*/ }ArcNode; typedef struct VNode{ int data; //the data of this node ArcNode *firstarc; //first link of this node }VNode;
二、图的创建:
CreatGraph(int n,VNode G[]) { int i,e; ArcNode *p,*q; printf("Input the data of each node\n"); for( i = 0; i < n; i++ ) { scanf("%d",&G[i].data); G[i].firstarc = NULL; } for( i = 0; i < n; i++ ) { printf("Creat the edges for the %dth vertex,end it with -1\n ",i); scanf("%d",&e); while( e != -1 ) { p = (ArcNode *)malloc(sizeof(ArcNode)); p->next = NULL; p->adjvex = e; if(G[i].firstarc == NULL) G[i].firstarc = p; else q->next = p; q = p; scanf("%d",&e); } } }
三、图的遍历算法用一下两个实现
(1)深度优先遍历:从图中某个顶点v出发,访问该顶点v,然后依次从v的未被访问的节点出发,继续深度优先遍历该图,直至与v相通的所有顶点均被访问为止。因为图不一定连通的,故可能会有未被访问的顶点,再从未被访问的顶点出发重复上述操作,直至所以顶点均被访问为止。核心为递归。
int visited[] = {0,0};
int next_link(VNode G[],int v) { ArcNode *p; p = G[v].firstarc; while( p != NULL ) { if( visited[p->adjvex] == 1 ) p = p->next; else return p->adjvex; } return -1; } void DFS(VNode G[],int v) { int w; printf("the %dth node,data:%d\n",v,G[v].data); visited[v] = 1; if(G[v].firstarc != NULL) w = ( G[v].firstarc )->adjvex; else w = -1; while( w != -1 ) { if(visited[w] == 0) DFS(G,w); w = next_link(G,w); } } void try_DFS(VNode G[],int n) { int i; for( i = 0; i < n; i++) { if( visited[i] == 0) DFS(G,i); } } void main() { int n; printf("please input the total number of nodes\n"); scanf("%d",&n); VNode G[n]; CreatGraph(n,G); try_DFS(G,n); }
(2)广度遍历:有着明显的层次关系,先访问第一层的顶点v,再访问v的各个未被访问的顶点,这些算第二层,再从第二层中点出发访问他们的未被访问的顶点,算第三层,依次下去。也因此,该算法更适合于树形结构,因为树形结构有着明显的分层结构。
因为要记录该顶点的下一层所有顶点,之后从这些顶点中继续遍历,记录下下一层所有顶点。故采用队列来记录这些顶点,每次均从队列首取出一个顶点,遍历之,并将其未被访问的相邻顶点放置队列末尾,遍历完了再从队列首取出一个顶点继续遍历。直至队列没有数了说明这个连通图遍历完了。
队列定义如下:
typedef struct QNode { int data[7]; int front,rear; }SeqQueue; void SeqQueueEnter( SeqQueue *q,int x ) { if( (q->rear + 1) % 7 == q->front ) printf("the queue is full\n"); q->data[q->rear] = x; q->rear = ( q->rear +1 ) % 7; } int SeqQueueOut( SeqQueue *q ) { if(q->rear == q->front) return -1; int x; x = q->data[q->front]; q->front ++; return x; }
广度遍历如下:
int next_link(VNode G[],int v) { ArcNode *p; p = G[v].firstarc; while( p != NULL ) { if( visited[p->adjvex] == 1 ) p = p->next; else return p->adjvex; } return -1; } void BFS(VNode G[],SeqQueue *q,G[v].data); visited[v] = 1; SeqQueueEnter(q,v); while( ( v = SeqQueueOut(q) ) != -1 ) { if(G[v].firstarc != NULL) w = ( G[v].firstarc )->adjvex; else w = -1; while( w != -1 ) { if(visited[w] == 0) { SeqQueueEnter(q,w); printf("the %dth node,w,G[w].data); visited[w] = 1; } w = next_link(G,v); } } } void try_BFS(VNode G[],int n) { int i; for( i = 0; i < n; i++) { if( visited[i] == 0) BFS( G,q,i ); } } void main() { int n; SeqQueue queue; queue.rear = queue.front = 0; printf("please input the total number of nodes\n"); scanf("%d",G); try_BFS(G,&queue,n); }原文链接:https://www.f2er.com/datastructure/382881.html