1. 程式人生 > >圖的鄰接表表示法(C語言)

圖的鄰接表表示法(C語言)

鄰接表

鄰接表結構
鄰接表資料結構型別如下:

#define  MaxVertices 100
typedef struct node{   //邊表 
   int adjvex;
   node* next;  
}EdgeNode;  

typedef struct{     //頂點表  
   int vertex;  
   EdgeNode* edgenext;  
}VertexNode;  

typedef VertexNode AdjList[MaxVertices];//頂點表陣列  

typedef struct{   
    AdjList adjlist;  
    int
n,e; }AdjMatrix;

注:邊表為連結串列結構,插入元素有頭插法和尾插法兩種,這裡以頭插法為例。

對應的,我們得到如下的結構:
鄰接表資料結構
我們以無向圖為例:
無向圖
寫出相應的鄰接矩陣:
鄰接表實際

鄰接表生成函式:

void CreateGraph(AdjMatrix* G)  
{  
    int i,j,k,w,v;  
    EdgeNode *s;  
    printf("輸入頂點數和邊數(中間以空格分開):");  
    scanf("%d%d",&G->n,&G->e);  

    printf("建立頂點表\n"
); for (i=0;i<G->n;i++) { //fflush(stdin); //如果 stream 指向輸入流(如 stdin),那麼 fflush 函式的行為是不確定的。 //故而使用 fflush(stdin) 是不正確的。 getchar(); printf("請輸入第%d個頂點的資訊:",i+1); G->adjlist[i].vertex=getchar(); G->adjlist[i].edgenext=NULL; } //前插法
printf("建立邊表\n"); for (k=0;k<G->e;k++) { printf("輸入有連線的頂點序號:"); scanf("%d%d",&i,&j); i-=1;j-=1; //① //對於直接相連的進行編入(即對輸入“0 1”時,在0對應的邊表中編入1) s=(EdgeNode*)malloc(sizeof(EdgeNode)); s->adjvex=j;//邊表賦值 s->next=G->adjlist[i].edgenext; G->adjlist[i].edgenext=s; //對於間接相連的進行編入(即對輸入“0 1”時,在1對應的邊表中編入0) s=(EdgeNode*)malloc(sizeof(EdgeNode)); s->adjvex=i; s->next=G->adjlist[j].edgenext; G->adjlist[j].edgenext=s; } }

鄰接表列印函式:

void DispGraph(AdjMatrix *G)
{
    int i;
    for (i=0;i<G->n;i++)  
    {  
        printf("%d->",i+1);  
        while(1)  
        {             
            if(G->adjlist[i].edgenext==NULL)
            {
                printf("^");
                break;  
            }
            printf("%d->",G->adjlist[i].edgenext->adjvex+1);
            //②
            G->adjlist[i].edgenext=G->adjlist[i].edgenext->next;  

        }  
        printf("\n");  
    }  
} 

注:①②處是由於邊表的順序是對應的是頂點表陣列的順序,所以起始陣列為G->adjlist[0],但是按照人們的輸入習慣,我們從1開始,所以對於每個輸入的i,j進行減1處理儲存,再對於輸出的G->adjlist[i].edgenext->adjvex進行加1處理,保證輸入輸出的統一性

具體程式碼實現:

#include <stdio.h>  
#include <stdlib.h>  
#define  MaxVertices 100
typedef struct node{   //邊表 
   int adjvex;
   node* next;  
}EdgeNode;  

typedef struct{     //頂點表  
   int vertex;  
   EdgeNode* edgenext;  
}VertexNode;  

typedef VertexNode AdjList[MaxVertices];  

typedef struct{   
    AdjList adjlist;  
    int n,e;  
}AdjMatrix;  

void CreateGraph(AdjMatrix* G)  
{  
    int i,j,k,w,v;  
    EdgeNode *s;  
    printf("輸入頂點數和邊數(中間以空格分開):");  
    scanf("%d%d",&G->n,&G->e);  

    printf("建立頂點表\n"); 
    for (i=0;i<G->n;i++)  
    {  
        //fflush(stdin);  
        //如果 stream 指向輸入流(如 stdin),那麼 fflush 函式的行為是不確定的。
        //故而使用 fflush(stdin) 是不正確的。
        getchar(); 
        printf("請輸入第%d個頂點的資訊:",i+1);
        G->adjlist[i].vertex=getchar();
        G->adjlist[i].edgenext=NULL;  
    }  
    //前插法 
    printf("建立邊表\n");  
    for (k=0;k<G->e;k++)  
    {  
       printf("輸入有連線的頂點序號:");  
       scanf("%d%d",&i,&j);  
       i-=1;j-=1;//①
       //對於直接相連的進行編入(即對輸入“0 1”時,在0對應的邊表中編入1) 
       s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=j;//邊表賦值 
       s->next=G->adjlist[i].edgenext;  
       G->adjlist[i].edgenext=s;  
       //對於間接相連的進行編入(即對輸入“0 1”時,在1對應的邊表中編入0)
       s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=i;  
       s->next=G->adjlist[j].edgenext;  
       G->adjlist[j].edgenext=s;  
    }  
}   
void DispGraph(AdjMatrix *G)
{
    int i;
    for (i=0;i<G->n;i++)  
    {  
        printf("%d->",i+1);  
        while(1)  
        {             
            if(G->adjlist[i].edgenext==NULL)
            {
                printf("^");
                break;  
            }
            printf("%d->",G->adjlist[i].edgenext->adjvex+1); 
            //② 
            G->adjlist[i].edgenext=G->adjlist[i].edgenext->next;  

        }  
        printf("\n");  
    }  
} 
int main()  
{  
   AdjMatrix* G= (AdjMatrix*)malloc(sizeof(AdjMatrix));  
   CreateGraph(G);  
   DispGraph(G); 
}