C/C++知识点之C语言建立有向图的邻接表及其遍历操作
小标 2018-10-10 来源 : 阅读 2554 评论 0

摘要:本文主要向大家介绍了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+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程