圖—鄰接表(建立,深度遍曆,廣度遍曆)

來源:互聯網
上載者:User

     圖的鄰接表標記法類似於樹的孩子鏈表標記法。對於圖G中的每個頂點vi
,該方法把所有鄰接於vi
的頂點vj
鏈成一個帶頭結點的單鏈表,這個單鏈表就稱為頂點vi
的鄰接表(Adjacency List)。

以下代碼測試過,為圖的鄰接表表示方式。

/************************************************************************/<br />/* 圖的鄰接表格儲存體結構 */<br />/************************************************************************/<br />#include <stdio.h><br />#define MaxVertexNum 100<br />#define QueueSize 30<br />typedef enum{FALSE,TRUE}Boolean;<br />Boolean visited[MaxVertexNum];<br />typedef char VertexType;<br />typedef int EdgeType;<br />typedef struct node//邊表結點<br />{<br />int adjvex;//鄰接點域<br />struct node *next;//域鏈<br />//若是要表示邊上的權,則應增加一個資料域<br />}EdgeNode;<br />typedef struct vnode//頂點邊結點<br />{<br />VertexType vertex;//頂點域<br />EdgeNode *firstedge;//邊表頭指標<br />}VertexNode;<br />typedef VertexNode AdjList[MaxVertexNum];//AdjList是鄰接表類型<br />typedef struct<br />{<br />AdjList adjlist;//鄰接表<br />int n,e;//圖中當前頂點數和邊數<br />}ALGraph;//對於簡單的應用,無須定義此類型,可直接使用AdjList類型<br />/************************************************************************/<br />/* 建立無向圖的鄰接表演算法 */<br />/************************************************************************/<br />void CreateGraphAL (ALGraph *G)<br />{<br /> int i,j,k;<br /> EdgeNode * s;<br /> printf("請輸入頂點數和邊數(輸入格式為:頂點數,邊數):/n");<br /> scanf("%d,%d",&(G->n),&(G->e)); // 讀入頂點數和邊數<br /> printf("請輸入頂點資訊(輸入格式為:頂點號<CR>)每個頂點以斷行符號作為結束:/n");<br /> for (i=0;i<G->n;i++) // 立有n個頂點的頂點表<br /> {<br /> scanf("/n%c",&(G->adjlist[i].vertex)); // 讀入頂點資訊<br /> G->adjlist[i].firstedge=NULL; // 點的邊表頭指標設為空白<br /> }<br /> printf("請輸入邊的資訊(輸入格式為:i,j):/n");<br /> for (k=0;k<G->e;k++) // 建立邊表<br /> {<br /> scanf("/n%d,%d",&i,&j); // 讀入邊<Vi,Vj>的頂點對應序號<br /> s=new EdgeNode; // 產生新邊表結點s<br /> s->adjvex=j; // 鄰接點序號為j<br /> s->next=G->adjlist[i].firstedge; // 將新邊表結點s插入到頂點Vi的邊表頭部<br /> G->adjlist[i].firstedge=s;<br />s=new EdgeNode;<br />s->adjvex=i;<br />s->next=G->adjlist[j].firstedge;<br />G->adjlist[j].firstedge=s;<br /> }<br />}<br />/************************************************************************/<br />/* 深度優先遍曆 */<br />/************************************************************************/<br />void DFS(ALGraph *G,int i)<br />{<br /> //以vi為出發點對鄰接表表示的圖G進行深度優先搜尋<br /> EdgeNode *p;<br />printf("visit vertex:%c/n",G->adjlist[i].vertex); // 訪問頂點vi<br />visited[i]=TRUE; //標記vi已訪問<br />p=G->adjlist[i].firstedge; //取vi邊表的頭指標<br />while(p)<br />{//依次搜尋vi的鄰接點vj,這裡j=p->adjvex<br />if (!visited[p->adjvex])//若vi尚未被訪問<br />DFS(G,p->adjvex);//則以Vj為出發點向縱深搜尋<br />p=p->next; //找vi的下一鄰接點<br />}<br />}<br />void DFSTraverseM(ALGraph *G)<br />{<br /> int i;<br /> for(i=0;i<G->n;i++)<br /> visited[i]=FALSE;<br /> for(i=0;i<G->n;i++)<br /> if(!visited[i])<br /> DFS(G,i);<br />}<br />/************************************************************************/<br />/* 廣度優先遍曆 */<br />/************************************************************************/<br />typedef struct<br />{<br /> int front;<br /> int rear;<br /> int count;<br /> int data[QueueSize];<br />}CirQueue;<br />void InitQueue(CirQueue *Q)<br />{<br /> Q->front=Q->rear=0;<br /> Q->count=0;<br />}<br />int QueueEmpty(CirQueue *Q)<br />{<br /> return Q->count=QueueSize;<br />}<br />int QueueFull(CirQueue *Q)<br />{<br /> return Q->count==QueueSize;<br />}<br />void EnQueue(CirQueue *Q,int x)<br />{<br /> if (QueueFull(Q))<br /> printf("Queue overflow");<br /> else<br /> {<br /> Q->count++;<br /> Q->data[Q->rear]=x;<br /> Q->rear=(Q->rear+1)%QueueSize;<br /> }<br />}<br />int DeQueue(CirQueue *Q)<br />{<br /> int temp;<br /> if(QueueEmpty(Q))<br /> {<br /> printf("Queue underflow");<br /> return NULL;<br /> }<br /> else<br /> {<br /> temp=Q->data[Q->front];<br /> Q->count--;<br /> Q->front=(Q->front+1)%QueueSize;<br /> return temp;<br /> }<br />}<br />void BFS(ALGraph*G,int k)<br />{// 以vk為源點對用鄰接表表示的圖G進行廣度優先搜尋<br /> int i;<br />CirQueue Q;//須將隊列定義中DataType改為int<br />EdgeNode *p;<br />InitQueue(&Q);//隊列初始化<br />printf("visit vertex:%c/n",G->adjlist[k].vertex);//訪問源點vk<br />visited[k]=TRUE;<br />EnQueue(&Q,k);//vk已訪問,將其人隊。(實際上是將其序號人隊)<br />while(!QueueEmpty(&Q))<br />{//隊非空則執行<br />i=DeQueue(&Q);//相當於vi出隊<br />p=G->adjlist[i].firstedge;//取vi的邊表頭指標<br />while(p)<br />{//依次搜尋vi的鄰接點vj(令p->adjvex=j)<br />if(!visited[p->adjvex])<br />{//若vj未訪問過<br />printf("visit vertex:%c",G->adjlist[p->adjvex].vertex);//訪問vj<br />visited[p->adjvex]=TRUE;<br />EnQueue(&Q,p->adjvex);//訪問過的vj人隊<br />}<br />p=p->next;//找vi的下一鄰接點<br />}<br />}<br />}<br />void BFSTraverseM(ALGraph *G)<br />{<br /> int i;<br /> for (i=0;i<G->n;i++)<br /> visited[i]=FALSE;<br /> for (i=0;i<G->n;i++)<br /> if (!visited[i])<br /> BFS(G,i);<br />}<br />/************************************************************************/<br />/* 主函數調用 */<br />/************************************************************************/<br />int main()<br />{<br />ALGraph G;<br />CreateGraphAL(&G);<br />printf("深度優先遍曆:/n");<br />DFSTraverseM(&G);<br />printf("廣度優先遍曆:/n");<br />BFSTraverseM(&G);<br />return 0;<br />}

測試結果如下:

 

如果測試有誤,若是代碼有錯,請指出,共同學習,呵呵。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.