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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM