摘要:本文主要向大家介绍了C/C++知识点之C语言建立有向图的邻接表及其遍历操作,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。
本文主要向大家介绍了C/C++知识点之C语言建立有向图的邻接表及其遍历操作,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。
1 /**/
2 #include"stdio.h"
3 #include"stdlib.h"
4 //图的邻接矩阵储存结构
5 typedef char elemtype;
6 #define maxsize 10
7 #define queuesize 100
8 //边结点的类型定义
9 typedef struct edgenode
10 {
11 int adjvex;//存放邻接的点在顶点表的下标,邻接点
12 struct edgenode *next;//指向Vi下一个邻接点的边结点
13 int weight;/*权值*/
14 }edgenode;
15 //顶点结点类型定义
16 typedef struct vexnode
17 {
18 elemtype data; //存储顶点的名称或其相关信息
19 edgenode *firstedge;//边表头指针
20 }vexnode;
21 //图的邻接表数据类型
22 typedef struct{
23 vexnode vexlist[maxsize];//顶点表
24 int n,e;
25 }graph;
26 //在图g中查找顶点v,存在顶点数组中的下标,不存在返回-1
27 int locatevex(graph g,elemtype v)
28 {
29 int i;
30 for(i=0;i<g.n;i++)
31 if(g.vexlist[i].data==v)return i;
32 return -1;
33 }
34 //打印图信息
35 void print(graph g)
36 {
37 int i;
38 edgenode *p;
39 printf("图的邻接表表示:");
40 for(i=0;i<g.n;i++){
41 printf("\n%4c",g.vexlist[i].data);
42 p=g.vexlist[i].firstedge;
43 while(p!=NULL){
44 printf("-->%d",p->adjvex);p=p->next;
45 }
46 }
47 printf("\n");
48 }
49 void creategraph(graph *g){
50 int i,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;k<g->e;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,int i)
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 int v;
104 for (v=0; v<g.n;v++)visited[v]=0; /*初始化标志数组*/
105 for (v=0; v<g.n;v++) /*保证非连通图的遍历*/
106 /*从第v个顶点出发递归地深度优先遍历图G*/
107 if (!visited[v])DFS(g,v);
108 }
109 //循环队列存储结构定义
110 typedef struct cirqueue
111 {
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 int queuelength(cirqueue q)
156 {
157 return (q.rear-q.front+queuesize) % queuesize;
158 }
159 //【算法6-10:利用邻接矩阵实现连通图的广度优先搜索遍历】
160 int BFSvisited[maxsize];
161 cirqueue q;
162 /*从第k个顶点出发广度优先遍历图G,G以邻接矩阵表示。*/
163 void BFS(graph g,int k){
164 int i;
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 int v;
187 for (v=0; v<g.n;v++) //初始化标志数组
188 visited[v]=0;
189 for (v=0; v<g.n;v++) //保证非连通图的遍历
190 if (!visited[v])BFS(g,v);
191 //从第v个顶点出发递归地深度优先遍历图G
192 }
193 int main()
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 }
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号