C语言建立有向图的邻接表及其遍历操作
生活随笔
收集整理的這篇文章主要介紹了
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
總結
以上是生活随笔為你收集整理的C语言建立有向图的邻接表及其遍历操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 勾股数性质
- 下一篇: 702:Crossing River (