#include<stdio.h> #include<stdlib.h> #define MAX_VERTAX_SIZE 20 #define OK 1 #define ERROR 0 typedef int Status; typedef char ElemType; typedef struct EageNode{ int adjacentVertax; struct EageNode* nextAdjacentVertax; }EageNode, *EageNodePtr; typedef struct VertaxNode{ ElemType data; EageNodePtr firstEage; }VertaxNode; typedef struct GraphAL{ VertaxNode VertaxArray[MAX_VERTAX_SIZE]; int vertaxNum; int eageNum; }GraphAL; //定义队列结构,用于图的广度优先遍历 typedef struct QueueNode{ ElemType data; struct QueueNode* next; }QueueNode, *QueueNodePtr; typedef struct Queue{ QueueNodePtr front; QueueNodePtr rear; }Queue; Status InitQueue(Queue* Q){ Q->front = (QueueNodePtr)malloc(sizeof(struct QueueNode)); if( !Q->front ) return ERROR; Q->rear = Q->front; Q->rear->next = NULL; return OK; } Status EnterQueue(Queue *q, ElemType value){ QueueNode* n; n = (QueueNode*)malloc(sizeof(struct QueueNode)); if( !n ) return ERROR; n->data = value; n->next = q->rear->next; q->rear->next = n; q->rear = n; return OK; } Status DeleteQueue(Queue* q,ElemType* value){ if( q->front == q->rear ) return ERROR; QueueNode* p; p = q->front->next; *value = p->data; q->front->next = p->next; free(p); if( p == q->rear ) q->rear = q->front; return OK; } int IsQueueEmpty(Queue q){ return q.front == q.rear ? OK : ERROR; } /* int main(){ Queue q; ElemType c; InitQueue(&q); EnterQueue(&q,'a'); EnterQueue(&q,'f'); EnterQueue(&q,'g'); EnterQueue(&q,'e'); DeleteQueue(&q,&c); printf("%c \n", c); printf("&&&&%d", IsQueueEmpty(q)); DeleteQueue(&q,&c); printf("%c \n", c); return 0; } */ //返回顶点v在G中的下标 int LocateVertax(GraphAL G, ElemType v){ int i; for( i = 0; i < G.vertaxNum; i++ ){ if( G.VertaxArray[i].data == v ) return i; } return -1; } //通过下标得到元素的值 ElemType GetValueFromIndex(GraphAL G, int index){ return G.VertaxArray[index].data; } //创建邻接表无向图 Status CreateUDG_AdjacencyList(GraphAL* G){ int i; ElemType v,w; int index_v, index_w; EageNodePtr vPtr,wPtr; printf(" Create Undigraph\n"); printf("Please enter the number of Vertax and Eage: "); scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum)); printf("ok, please input the value of %d Vertax\n", G->vertaxNum); for( i = 0; i < G->vertaxNum; i++ ){ scanf("%c%*c", &(G->VertaxArray[i].data)); G->VertaxArray[i].firstEage = NULL; } for( i = 0; i < G->eageNum; i++ ){ printf("ok, please input the two Vertax of Eage %d (Sepearted by Space) :", i+1); scanf("%c %c%*c", &v,&w); //一条边的两个顶点v w index_v = LocateVertax(*G, v); index_w = LocateVertax(*G, w); wPtr = (EageNode*)malloc(sizeof(EageNode)); if( !wPtr ) return ERROR; wPtr->adjacentVertax = index_w; wPtr->nextAdjacentVertax = G->VertaxArray[index_v].firstEage; G->VertaxArray[index_v].firstEage = wPtr; vPtr = (EageNode*)malloc(sizeof(EageNode)); if( !vPtr ) return ERROR; vPtr->adjacentVertax = index_v; vPtr->nextAdjacentVertax = G->VertaxArray[index_w].firstEage; G->VertaxArray[index_w].firstEage = vPtr; } return OK; } //在图G中找v的第一个邻接顶点,找到则返回该顶点在邻接表中的位置,若没有则返回-1 int FirstAdjacentVertax(GraphAL G, ElemType v){ int index_v; index_v = LocateVertax(G, v); if( G.VertaxArray[index_v].firstEage == NULL ) return -1; else return (G.VertaxArray[index_v].firstEage)->adjacentVertax; } //在图G中找v的从w开始的下一个相邻的顶点 int NextAdjacentVertax(GraphAL G, ElemType v, ElemType w ){ int index_v,index_w; EageNodePtr p; index_v = LocateVertax(G, v); index_w = LocateVertax(G, w); if( G.VertaxArray[index_v].firstEage == NULL ) return -1; p = G.VertaxArray[index_v].firstEage; //p pointer to first node while( p->nextAdjacentVertax != NULL ){ if( p->adjacentVertax == index_w ) return p->nextAdjacentVertax->adjacentVertax; p = p->nextAdjacentVertax; } return -1; } //DFS深度优先遍历图:使用递归算法,算法思想: // 1:从v顶点开始,visit(v),将其设置为已遍历 // 2: 获得v的第一个邻接顶点w,若其存在并且没有访问过,递归遍历; // 3: 获得v的从w之后的邻接点,若其存在并且没有访问过,递归遍历;直到所有都访问过 int visitedArray[MAX_VERTAX_SIZE]; void visit(ElemType c){ printf("%c ", c); } Status DFS(GraphAL G, ElemType v){ ElemType w; visit(v); visitedArray[LocateVertax(G, v)] = 1; for( w = GetValueFromIndex(G, FirstAdjacentVertax(G, v)); LocateVertax(G, w) != -1; w = GetValueFromIndex(G, NextAdjacentVertax(G, v, w))){ if( visitedArray[LocateVertax(G, w)] != 1 ) DFS(G, w); } return OK; } Status DFSTraverse(GraphAL G){ int i; for( i = 0; i < G.vertaxNum; i++ ) visitedArray[i] = 0; for( i = 0; i < G.vertaxNum; i++ ) if( visitedArray[i] != 1 ) DFS(G, GetValueFromIndex(G, i)); return OK; } //BFS(Breadth First Search) Status BFS(GraphAL G){ int i,j; Queue q; ElemType c; InitQueue(&q); for(i = 0; i < G.vertaxNum; i++) visitedArray[i] = 0; for(i = 0; i < G.vertaxNum; i++){ //这个for实际执行的次数是连通分量的个数 if( visitedArray[i] == 0 ){ EnterQueue(&q, G.VertaxArray[i].data); visitedArray[i] = 1; while( IsQueueEmpty(q) != OK ){ DeleteQueue(&q, &c); visit(c); for( j = FirstAdjacentVertax(G, c); j != -1; j = NextAdjacentVertax(G, c, GetValueFromIndex(G, j))){ if( visitedArray[j] == 0 ){ EnterQueue(&q, GetValueFromIndex(G, j)); visitedArray[j] = 1; } } } } } } //打印无向图的邻接表 void PrintUDG_AdjacentList(GraphAL G){ int i; EageNodePtr p; printf(" Adjacency List \n"); for( i = 0; i < G.vertaxNum; i++ ){ printf(" %d %c ",i, G.VertaxArray[i]); p = G.VertaxArray[i].firstEage; while( p != NULL ){ printf("-->%d", p->adjacentVertax); p = p->nextAdjacentVertax; } printf("\n"); } } int main(){ GraphAL G; CreateUDG_AdjacencyList(&G); PrintUDG_AdjacentList(G); printf(" DFS(Depth First Search) of UDG(Undigraph)\n"); DFSTraverse(G); printf("\n BFS(Breadth First Search) of UDG(Undigraph)\n"); BFS(G); return 0; }