标签:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define MAXSIZE 30 4 5 typedef struct node1//邻接表结点 6 { 7 int adjvex;//邻接点域 8 struct node1 *next;//指向下一个邻接边结点的指针域 9 }EdgeNode;//邻接表结点类型 10 11 typedef struct vnode//顶点表结点 12 { 13 int vertex;//顶点域 14 EdgeNode *firstedge;//指向邻接表的第一个邻接结点的指针域 15 }VertexNode;//顶点表结点类型 16 17 void CreatAdjlist(VertexNode g[],int e,int n)//建立无向图的邻接表,n为顶点数,e为边数,g[]存储n个顶点表结点 18 { 19 EdgeNode *p; 20 int i,j,k; 21 printf("Input data of veter(0~n-1);\n"); 22 for(i=0;i<n;i++)//建立有n个顶点的顶点表 23 { 24 g[i].vertex=i;//读入顶点信息 25 g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针 26 } 27 for(k=1;k<=e;k++)//输入e条边 28 { 29 printf("Input edge of(i,j):"); 30 scanf("%d,%d",&i,&j); 31 p=(EdgeNode*)malloc(sizeof(EdgeNode)); 32 p->adjvex=j;//在顶点Vi的邻接表中添加邻接点为j的结点 33 p->next=g[i].firstedge;//插入是在邻接表表头进行的 34 g[i].firstedge=p; 35 p=(EdgeNode*)malloc(sizeof(EdgeNode)); 36 p->adjvex=i;//在顶点Vj的邻接表中添加邻接点为i的结点 37 p->next=g[j].firstedge;//插入是在邻接表表头进行的 38 g[j].firstedge=p; 39 } 40 } 41 42 typedef struct node 43 { 44 int data; 45 struct node *next; 46 }QNode;//链队列结点的类型 47 48 typedef struct 49 { 50 QNode *front,*rear;//将头、尾指针纳入到一个结构体的链队列 51 }LQueue;//链队列类型 52 53 void Init_LQueue(LQueue **q)//创建一个带头结点的空队列 54 { 55 QNode *p; 56 *q=(LQueue*)malloc(sizeof(LQueue));//申请带头、尾指针的链队列 57 p=(QNode*)malloc(sizeof(QNode));//申请链队列的头结点 58 p->next=NULL;//头结点的next指针置为空 59 (*q)->front=p;//队头指针指向头结点 60 (*q)->rear=p;//队尾指针指向头结点 61 } 62 63 int Empty_LQueue(LQueue *q)//判断队是否为空 64 { 65 if(q->front==q->rear)//队为空 66 return 1; 67 else 68 return 0; 69 } 70 71 72 void In_LQueue(LQueue *q,int x)//入队 73 { 74 QNode *p; 75 p=(QNode *)malloc(sizeof(QNode));//申请新链队列结点 76 p->data=x; 77 p->next=NULL;//新结点作为队尾结点时其next域为空 78 q->rear->next=p;//将新结点*p链到原队尾结点之后 79 q->rear=p;//使队尾指针指向新的队尾结点*p 80 } 81 82 void Out_LQueue(LQueue *q,int *x)//出队 83 { 84 QNode *p; 85 if(Empty_LQueue(q)) 86 printf("Queue is empty!\n");//队空出队失败 87 else 88 { 89 p=q->front->next;//指针p指向链队列第一个数据结点(即队头结点 90 q->front->next=p->next;//头结点的next指针指向链队列的第二个数据结点(即删除第一个数据结点) 91 *x=p->data;//将删除的队头结点数据由x返回 92 free(p); 93 if(q->front->next==NULL)//出队后若队为空则置为空队列 94 q->rear=q->front; 95 } 96 } 97 98 int visited[MAXSIZE];//MAXSIZE为大于或等于无向图顶点个数的常量 99 void BFS(VertexNode g[],LQueue *Q,int i)//广度优先搜索遍历邻接表存储的图,g为顶点表,Q为队指针,i为第i个顶点 100 { 101 int j,*x=&j;//出队顶点将由指针x传给j 102 EdgeNode *p; 103 printf("%4d",g[i].vertex);//输出顶点i信息,即访问顶点i 104 visited[i]=1;//置顶点i为访问过标志 105 In_LQueue(Q,i);//顶点i入队Q 106 while(!Empty_LQueue(Q))//当队Q非空时 107 { 108 Out_LQueue(Q,x);//队头顶点出队经由指针x送给就j(暂计为顶点j) 109 p=g[j].firstedge;//根据顶点j的表头指针查找其邻接表的第一个邻接边结点 110 while(p!=NULL)//当邻接边结点非空时 111 { 112 if(!visited[p->adjvex])//输出这个邻接边结点的顶点信息 113 { 114 printf("%4d",g[p->adjvex].vertex);//输出这个邻接边结点的顶点信息 115 visited[p->adjvex]=1;//置该邻边结点为访问过的标志 116 In_LQueue(Q,p->adjvex);//将该邻接边结点送入队列Q 117 } 118 p=p->next;//在顶点j的邻接表中查找j的下一个邻接边结点 119 } 120 } 121 } 122 123 void main() 124 { 125 int e,n; 126 VertexNode g[MAXSIZE];//定义顶点表结点类型的数组g 127 LQueue *q; 128 printf("Input number of node:\n");//输入图中结点的个数 129 scanf("%d",&n); 130 printf("Input number of edge:\n");//输入图中边的个数 131 scanf("%d",&e); 132 printf("Make adjlist:\n"); 133 CreatAdjlist(g,e,n);//建立无向图的链接表 134 Init_LQueue(&q);//队列q初始化 135 printf("BFSTraverse:\n"); 136 BFS(g,q,0);//广度优先遍历以邻接表存储的无向图 137 printf("\n"); 138 }
说明:
遍历邻接边和图具体如下:
出入队顺序:
标签:
原文地址:http://www.cnblogs.com/wxdjss/p/5498451.html