1 /*C语言建立有向图的邻接表及其遍历操作*/
2 #include"stdio.h"
3 #include"stdlib.h"
4 //图的邻接矩阵储存结构
5 typedef charelemtype;6 #define maxsize 10
7 #define queuesize 100
8 //边结点的类型定义
9 typedef structedgenode10 {11 int adjvex;//存放邻接的点在顶点表的下标,邻接点
12 struct edgenode *next;//指向Vi下一个邻接点的边结点
13 int weight;/*权值*/
14 }edgenode;15 //顶点结点类型定义
16 typedef structvexnode17 {18 elemtype data; //存储顶点的名称或其相关信息
19 edgenode *firstedge;//边表头指针
20 }vexnode;21 //图的邻接表数据类型
22 typedef struct{23 vexnode vexlist[maxsize];//顶点表
24 intn,e;25 }graph;26 //在图g中查找顶点v,存在顶点数组中的下标,不存在返回-1
27 intlocatevex(graph g,elemtype v)28 {29 inti;30 for(i=0;i
35 voidprint(graph g)36 {37 inti;38 edgenode *p;39 printf("图的邻接表表示:");40 for(i=0;i%d",p->adjvex);p=p->next;45 }46 }47 printf("\n");48 }49 void creategraph(graph *g){50 inti,j,k;51 elemtype v1,v2;52 edgenode *s;53 printf("请输入图的顶点数及边数\n");54 printf("顶点数 n=");scanf("%d",&g->n);55 printf("边 数 e=");scanf("%d",&g->e);56 printf("请输入图的顶点信息:\n");getchar();57 for(i=0;i<=g->n;i++){58 scanf("%c",&g->vexlist[i].data); //构造顶点信息
59 g->vexlist[i].firstedge=NULL;60 }61 printf("请输入图的边的信息:\n");62 for(k=0;ke;k++)63 {64 printf("请输入第%d条边的两个端点下标:",k+1);65 scanf("%c%c",&v1,&v2);getchar();//输入一条边的两个顶点
66 i=locatevex(*g,v1);67 j=locatevex(*g,v2);68 if(i>=0&&j>=0){69 //建立无向图的邻接表
70 /*s=(edgenode *)malloc(sizeof(edgenode));71 s->adjvex=j;72 s->next=g->vexlist[i].firstedge;73 g->vexlist[i].firstedge=s;74
75 s=(edgenode *)malloc(sizeof(edgenode));76 s->adjvex=i;77 s->next=g->vexlist[j].firstedge;78 g->vexlist[j].firstedge=s;*/
79 //建立有向图的邻接表
80 s=(edgenode *)malloc(sizeof(edgenode));81 s->adjvex=j;82 s->next=g->vexlist[i].firstedge;83 g->vexlist[i].firstedge=s;84 }85 }86 }87 int visited[maxsize];/*访问标志数组*/
88 /*从第i个顶点出发递归地深度优先遍历图G*/
89 void DFS(graph g,inti)90 {91 edgenode *p;92 printf("%3c",g.vexlist[i].data);/*访问第i个项点*/
93 visited[i]=1;94 p=g.vexlist[i].firstedge;95 while(p!=NULL) {96 if(visited[p->adjvex]==0)97 DFS(g,p->adjvex);/*对i的尚未访问的邻接顶点j递归调用DFS*/
98 p=p->next;99 }100 }101 void DFStraverse(graph g) /*对图G进行深度优先遍历*/
102 {103 intv;104 for (v=0; v
105 for (v=0; v
106 /*从第v个顶点出发递归地深度优先遍历图G*/
107 if (!visited[v])DFS(g,v);108 }109 //循环队列存储结构定义
110 typedef structcirqueue111 {112 elemtype *data; //队列存储空间的首地址
113 int front; //队头位置:指向当前队头元素
114 int rear; //队尾位置:指向当前队尾元素的下一位置
115 }cirqueue; //循环队列116 //构造空队,如果成功,返回1,如果失败,返回0
117 int initqueue(cirqueue *q)118 {119 q->data=(elemtype *)malloc(queuesize*sizeof(cirqueue));120 if (q->data==NULL)return 0; //存储分配失败
121 q->front=q->rear=0;122 return 1;123 }124 //插入元素e为Q的新的队尾元素 ,如果成功,返回1,如果失败,返回0
125 int enqueue (cirqueue *q,elemtype e)126 {127 if ((q->rear+1) % queuesize == q->front)128 return 0; //队列满
129 q->data[q->rear] =e;130 q->rear = (q->rear+1) % queuesize; //队尾后移一位
131 return 1;132 }133 //若队列不空,则删除Q的队头元素,用e返回其值,并返回1;否则返回0
134 int dequeue (cirqueue *q,int *e)135 {136 if (q->front == q->rear) return 0; //队列为空
137 *e = q->data[q->front];138 q->front = (q->front+1) %queuesize; //队头后移一位
139 return 1;140 }141 //若栈不空,则用e返回队头元素,并返回1;否则返回0
142 int getfront(cirqueue q,elemtype *e)143 {144 if (q.front == q.rear) return 0; //队列为空
145 *e=q.data[q.front];146 return 1;147 }148 //若队列为空栈,则返回1,否则返回0
149 int queueempty(cirqueue q)//栈非空
150 {151 if(q.front == q.rear)return 1; //队列为空
152 else return 0;153 }154 //返回队列的元素个数,即队列的长度
155 intqueuelength(cirqueue q)156 {157 return (q.rear-q.front+queuesize) %queuesize;158 }159 //【算法6-10:利用邻接矩阵实现连通图的广度优先搜索遍历】
160 intBFSvisited[maxsize];161 cirqueue q;162 /*从第k个顶点出发广度优先遍历图G,G以邻接矩阵表示。*/
163 void BFS(graph g,intk){164 inti;165 edgenode *p;166 initqueue(&q);/*初始化队列*/
167 printf("%3c",g.vexlist[k].data);/*访问第k个项点*/
168 visited[k]=1;169 enqueue(&q,k);/*第k个顶点进队*/
170 while(queueempty(q)==0) {/*队列非空*/
171 dequeue(&q,&i);172 p=g.vexlist[i].firstedge;/*获取第1个邻接点*/
173 while(p!=NULL){174 if(visited[p->adjvex]==0){175 /*访问第i个顶点的末曾访问的顶点*/
176 printf("%3c",g.vexlist[p->adjvex].data);177 visited[p->adjvex]=1;178 enqueue(&q,p->adjvex);/*第k个顶点进队*/
179 }180 p=p->next;181 }182 }183 }184 void BFStraverse(graph g) //对图G进行广度优先遍历
185 {186 intv;187 for (v=0; v
188 visited[v]=0;189 for (v=0; v
190 if (!visited[v])BFS(g,v);191 //从第v个顶点出发递归地深度优先遍历图G
192 }193 intmain()194 {195 graph g;196 creategraph(&g);197 print(g);198 printf("\n");199 printf("图的深度优先遍历序列:\n");200 DFStraverse(g);201 printf("\n");202 printf("图的广度优先遍历序列:\n");203 BFStraverse(g);204 printf("\n");205 return 0;206 }