數據結構無向圖的建立和遍歷(鄰接矩陣)


  圖主要分為無向圖、有向圖和網。存儲方式主要是鄰接矩陣和鄰接表,接下來我寫的是數據結構無向圖鄰接矩陣的構建方法

1.結構體

#define MAX  20   //邊和頂點的最大數量 
typedef char ElemType;
typedef struct Graph{
    int vexNum;  //頂點數
    int arcNum;  //邊的數量 
    ElemType vexs[MAX];       //頂點信息 
    int arcs[MAX][MAX];    //邊的信息 
}Graph,*myGraph;

2.構建圖

void createGraph(myGraph &G)
{
    G=(Graph*)malloc(sizeof(Graph));  //結構體的指針要初始化
     
    int i,j,k;
    int vexNum,arcNum;
    char v1,v2;    //邊的兩個頂點 
    printf("請輸入頂點的數量:");
    scanf("%d",&G->vexNum);
    printf("請輸入邊的數量:");
    scanf("%d",&G->arcNum);
    
    printf("請依次將頂點數據輸入進來\n");
    for(i=0;i<G->vexNum;i++)
    {   
        getchar();
        scanf("%c",&G->vexs[i]); 
    }
    
    for(i=0;i<G->vexNum;i++)
    {
        for(j=0;j<G->vexNum;j++)
        {
            G->arcs[i][j]=0;//初始化矩陣 
        }
    }
    
    printf("請依次將邊輸入進來\n");
    for(i=0;i<G->arcNum;i++)
    {
        getchar();
        scanf("%c%c",&v1,&v2);
        j=getLocate(G,v1);
        k=getLocate(G,v2);
        G->arcs[j][k]=1;
        G->arcs[k][j]=1;
    }
}

3.輸出鄰接矩陣

void printfGraph(myGraph G)
{
    int i,j;
    printf("  "); 
    for(i=0;i<G->vexNum;i++)
    {
        printf("%c ",G->vexs[i]);
    }
    printf("\n");
    for(i=0;i<G->vexNum;i++)
    {
        printf("%c ",G->vexs[i]);
        for(int j=0;j<G->vexNum;j++)
        {
            printf("%d ",G->arcs[i][j]);
        }
        printf("\n");
    }
}

4.圖的深度優先遍歷

深度優先遍歷:先遍歷第一元素頂點,在遍歷該頂點最近的鄰接點,如此反復循環,如果無法找到鄰接點,則返回回來

void DFS(myGraph G,int i,int *visit)
{
    int j;
    if(!visit[i])
    {
        visit[i]=1;  //代表該頂點已被遍歷
        printf("%c ",G->vexs[i]);
        for(int j=0;j<G->vexNum;j++)
        {
            if(!visit[j]&&G->arcs[i][j]==1) //訪問沒有被訪問過得鄰接點 
            {
                DFS(G,j,visit);
            }
        }
    } 
}

5.圖的廣度優先遍歷:從圖中某一個頂點出發,再依次訪問所有的鄰接點,直至所有的頂點均被訪問為止

void BFS(myGraph G,int *visit)  //滿足隊列先進先出的特性 
{
    int front=0;
    int rear=0;
    int Queue[MAX]; //儲存每個數據的下標 
    int i,j,k;
    
    for(i=0;i<G->vexNum;i++)
    {
        visit[i]=0;   //先經過了深度優先遍歷,先全部變成未訪問 
    }
    
    for(i=0;i<G->vexNum;i++) //避免出現個人沒有邊的頂點 
    {
        if(!visit[i])
        {
            visit[i]=1;  //該頂點已被訪問
            printf("%c ",G->vexs[i]);
            Queue[rear++]=i;   //第一元素的下標 
        }
        while(front!=rear)
        {
            j=Queue[front++];
            
            for(k=firstVertex(G,j);k>=0;k=nextVertex(G,j,k))  //將出隊列的所有節點的鄰接點都入隊
            {
                if(!visit[k])//如果沒有被訪問過 
                {
                    visit[k]=1;
                    Queue[rear++]=k;
                    printf("%c ",G->vexs[k]);
                }
            }
        }
    }
} 

所有的代碼如下:

#include<stdio.h>
#include<stdlib.h> 

#define MAX  20   //邊和頂點的最大數量 
typedef char ElemType;
typedef struct Graph{
    int vexNum;  //頂點數
    int arcNum;  //邊的數量 
    ElemType vexs[MAX];       //頂點信息 
    int arcs[MAX][MAX];    //邊的信息 
}Graph,*myGraph;

//獲取頂點的下標
int getLocate(myGraph G,char v)
{
    int i;
    for(i=0;i<G->vexNum;i++)
    {
        if(v==G->vexs[i])
        {
            return i;
        }
    }
    return -1;
}
 

//圖的創建
void createGraph(myGraph &G)
{
    G=(Graph*)malloc(sizeof(Graph));  //結構體的指針要初始化
     
    int i,j,k;
    int vexNum,arcNum;
    char v1,v2;    //邊的兩個頂點 
    printf("請輸入頂點的數量:");
    scanf("%d",&G->vexNum);
    printf("請輸入邊的數量:");
    scanf("%d",&G->arcNum);
    
    printf("請依次將頂點數據輸入進來\n");
    for(i=0;i<G->vexNum;i++)
    {   
        getchar();
        scanf("%c",&G->vexs[i]); 
    }
    
    for(i=0;i<G->vexNum;i++)
    {
        for(j=0;j<G->vexNum;j++)
        {
            G->arcs[i][j]=0;//初始化矩陣 
        }
    }
    
    printf("請依次將邊輸入進來\n");
    for(i=0;i<G->arcNum;i++)
    {
        getchar();
        scanf("%c%c",&v1,&v2);
        j=getLocate(G,v1);
        k=getLocate(G,v2);
        G->arcs[j][k]=1;
        G->arcs[k][j]=1;
    }
}

//返回第一個鄰接點坐標 
int firstVertex(myGraph G,int i)
{
    if(i<0||i>(G->vexNum-1))
    {
        printf("輸入的下標不正確\n");
        return -1;
    }
    else
    {
        int j;
        for(int j=0;i<G->vexNum;j++)
        {
            if(G->arcs[i][j]==1)
            {
                return j;
            }
        }
        return -1;    
    }
}

//返回下一個鄰接點坐標 
int nextVertex(myGraph G,int i,int j)
{
    if(i<0||i>(G->vexNum-1)||j<0||j>(G->vexNum-1))
    {
        printf("輸入的下標不正確\n");
        return -1;
    }
    else
    {
        int k;
        for(k=j+1;k<G->vexNum;k++)
        {
            if(G->arcs[i][k]==1)
            {
                return k;
            }
        }
        return -1;
    }
}

//圖的深度優先遍歷
void DFS(myGraph G,int i,int *visit)
{
    int j;
    if(!visit[i])
    {
        visit[i]=1;  //代表該頂點已被遍歷
        printf("%c ",G->vexs[i]);
        for(int j=0;j<G->vexNum;j++)
        {
            if(!visit[j]&&G->arcs[i][j]==1) //訪問沒有被訪問過得鄰接點 
            {
                DFS(G,j,visit);
            }
        }
    } 
}

//圖的廣度優先遍歷
void BFS(myGraph G,int *visit)  //滿足隊列先進先出的特性 
{
    int front=0;
    int rear=0;
    int Queue[MAX]; //儲存每個數據的下標 
    int i,j,k;
    
    for(i=0;i<G->vexNum;i++)
    {
        visit[i]=0;   //先經過了深度優先遍歷,先全部變成未訪問 
    }
    
    for(i=0;i<G->vexNum;i++) //避免出現個人沒有邊的頂點 
    {
        if(!visit[i])
        {
            visit[i]=1;  //該頂點已被訪問
            printf("%c ",G->vexs[i]);
            Queue[rear++]=i;   //第一元素的下標 
        }
        while(front!=rear)
        {
            j=Queue[front++];
            
            for(k=firstVertex(G,j);k>=0;k=nextVertex(G,j,k))  //將出隊列的所有節點的鄰接點都入隊
            {
                if(!visit[k])//如果沒有被訪問過 
                {
                    visit[k]=1;
                    Queue[rear++]=k;
                    printf("%c ",G->vexs[k]);
                }
            }
        }
    }
} 

//鄰接矩陣的打印 
void printfGraph(myGraph G)
{
    int i,j;
    printf("  "); 
    for(i=0;i<G->vexNum;i++)
    {
        printf("%c ",G->vexs[i]);
    }
    printf("\n");
    for(i=0;i<G->vexNum;i++)
    {
        printf("%c ",G->vexs[i]);
        for(int j=0;j<G->vexNum;j++)
        {
            printf("%d ",G->arcs[i][j]);
        }
        printf("\n");
    }
}

int main()
{    
     myGraph G;
     createGraph(G);  //圖的鄰接矩陣的建立 
     printfGraph(G);   //圖的輸出 
     
     printf("深度優先搜索如下:\n");
     int visit[G->vexNum]={0};
     for(int i=0;i<G->vexNum;i++) //這里for循環是為了出現沒有被連接邊的頂點 
     {
         DFS(G,i,visit);  //深度優先搜索 
     }
     
     printf("\n");
     printf("廣度優先搜索如下:\n");
     BFS(G,visit);
     free(G);
}

  該程序的圖的功能可以正常實現,但是圖的廣度優先遍歷會使程序崩潰,但是排序沒有問題,還沒有找到是什么原因導致的


免責聲明!

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



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