C语言建立有向图的邻接表及其遍历操作

  1 /*C语言建立有向图的邻接表及其遍历操作*/
  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 }

原文地址:https://www.cnblogs.com/1772642558sgzj/p/9354882.html

时间: 2024-10-13 00:31:23

C语言建立有向图的邻接表及其遍历操作的相关文章

ACM:最短路,dijkstra,邻接表的建立,使用邻接表跟优先队列的dijkstra,Bellman-Ford,Floyd。。

(一)dijkstra,邻接矩阵 所有边权均为正,不管有没有环,求单个源点出发,到所有节点的最短路.该方法同时适用于有向图和无向图. #include <iostream> #include <string> #include <stack> using namespace std; const int MAXN = 1000; const int INF = 100000000; int n, m; int maze[MAXN][MAXN], vis[MAXN], d

数据结构之---C语言实现图的邻接表存储表示

// 图的数组(邻接矩阵)存储表示 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME 3 // 顶点字符串的最大长度+1 #define MAX_VERTEX_NUM 20 typedef int InfoType; // 存放网的权值 typedef char VertexType[MAX_NAME]; // 字符串类型 typedef enum{DG, DN, AG

图的邻接表+深度优先遍历+广度优先遍历

1 /** 2 无向图的邻接表存储 3 深度优先遍历递归 4 广度优先遍历递归+非递归 5 */ 6 #include <stdio.h> 7 #include <string.h> 8 #include <malloc.h> 9 #define N 5 10 #define MAX 50 11 typedef struct A{ 12 int adjvex; 13 struct A* nextArc; 14 }Arc; 15 typedef struct node{

有向图的邻接表

#include<iostream> using namespace std; #include<malloc.h> #define MAX_VERTEX_NUM 20 #define VerTexType char typedef enum{DG,DN,UDG,UDN}GraphKind; typedef struct ArcNode//边结点 { int adjvex;//邻结顶点的顶点序号 double weight; struct ArcNode *next; }ArcNo

图的邻接表(广度优先遍历,深度优先遍历,最小生成树(Kruskal算法))

main.h: #include <iostream> #include <queue> #define DefaultSize 10 #define maxWeight -1 using namespace std; template<typename T,typename E> struct Edge { int dest; E cost; Edge<T,E> *link; Edge(int d=0,int c=0):dest(d),cost(c),li

图的存储-邻接表

图的邻接表之前实现的时候,一直有点小问题 现在才明白 原来头结点是有内容的,之前一直当做一个标志位置来使用 说到底,这就是一种顺式和链式相互结合的储存结构 但还是不知其所以然,这个结构相较于邻接矩阵除了空间储存上面有很大优势,还有访问邻接节点方便 不明白他还有什么非他不可的理由 (其实就是因为自己对链式结构操作不是很熟悉找了个借口.) 邻接表(Adjacency List)是图的一种顺序存储与链式存储结合的存储方法.邻接表表示法类似于树的孩子链表表示法.就是对于图G 中的每个顶点vi,将所有邻接

构建有向图邻接表

建立一个有向图的邻接表,首先要构思好它的邻接表里面包含哪些结构数据,然后根据哪些数据来建立相应的结构体.但也要注意数据的输入. #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 10 typedef struct ArcNode //弧节点结构体 { int adjvex; //该弧指向定点的位置 int data; struct ArcNode * nextarc; //指向下下一条弧的指针 }ArcNode; typ

图的广度度优先遍历算法运用队列主针对邻接表有向图

源代码如下: #include<iostream> using namespace std; #define MAX_VERTEX_NUM 20 typedef int EdgeData; typedef char VertexData; //顶点数据域 typedef struct node { // 边表节点 EdgeData cost; //边上d权值 int adjvex; //邻接点域 struct node *next; //下一边链接指针 }EdgeNode; typedef s

邻接表求有向图各顶点的入度和出度 (图论基础)

有向图的邻接表用一个结构体LGraph存储表示,其中包括3个成员:顶点数组vertexs,顶点数vexnum和边数arcnum,其中顶点数组vertexs中每个元素都是VNode结构体变量.VNode结构体变量次年初图中每个顶点,它包含3个成员:顶点信息,出边表的表头指针和入边表的表头指针,其中后面两个成员都是ArcNode结构体类型的指针.ArcNode结构体存储边链表中的边节点,它包含两个成员:变的另一个邻接点的序号,以及指向下一个边节点的指针. #define MAXN 100 struc