數據結構->圖的鄰接表存儲(C語言)

一個無向圖G,五個頂點,8條邊,用鄰接表形式表示該圖



那麼該如何用C語言來表達呢?

首先看看我們的無向圖的頭文件ALGraph.h
其中最關鍵的是邊表和頂點表
邊表是關聯頂點與其他頂點之間的關聯
而頂點表是一個數組,保存所有的頂點,每個頂點內保存着頂點編號、權值 以及 邊表頭


聰明的你不難看出,這其實類似一個二維數組,只不過最裏層的是一個不定長數組

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef ALGRAPH_H_INCLUDED
#define ALGRAPH_H_INCLUDED

#define MAXVERTEXNUM 1000 //最大頂點數

//定義一個頂點類型
typedef unsigned char VertexType;
typedef unsigned char WeightType;

//邊表結點
typedef struct EDGENODE
{
    int adjVertex;//邊編號
    struct EDGENODE * nextNode;
} EdgeNode;

//頂點表結點
typedef struct VERTEXNODE
{
    VertexType vertex; //頂點值
    WeightType weight;//權值
    EdgeNode * FirstEdge;//第一邊結點
} VertexNode;

//頂點表類型
typedef VertexNode AdjList[MAXVERTEXNUM];

//圖
typedef struct ALGRAPH
{
    AdjList adjlist;
    int VertexNum;//頂點數
    int EdgeNum;//邊數
} ALGraph;

/**
* 函數的定義
*/
//圖的初始化
int ALGraph_init(ALGraph ** pg);
//創建圖
int Create_ALGraph(ALGraph * g);
//輸出圖結構
void Output_ALGraph(ALGraph *g);

#endif // ALGRAPH_H_INCLUDED



接下來是源文件ALGraph.c,用於實現創建圖等操作,重要地方都有註釋,最後遍歷鄰接表的方法類似二維不定長數組的遍歷

#include "ALGraph.h"

//圖的初始化
int ALGraph_init(ALGraph ** pg)
{
    *pg = (ALGraph *)malloc(sizeof(ALGraph));
    if(*pg==NULL)//內存分配失敗
    {
        return -1;
    }
    memset(*pg,0,sizeof(ALGraph));//內存內容全部填充爲0
    return 0;
}

//創建圖
int Create_ALGraph(ALGraph * g)
{
    if(g==NULL)
    {
        printf("創建圖時發現錯誤,未完成初始化操作!\n");
        return -1;
    }
    printf("請輸入頂點數: ");
    scanf("%d",&(g->VertexNum));
    fflush(stdin);

    printf("請輸入邊數: ");
    scanf("%d",&(g->EdgeNum));
    fflush(stdin);

    if(g->EdgeNum < g->VertexNum - 1) // N個結點至少需要N-1條邊
    {
        printf("邊數的值不合法!\n");
        return -1;
    }

    //*****************************************************************
    printf("開始創建頂點表vertexlist\n");
    int n;
    for(n=0; n<g->VertexNum; n++)
    {
        fflush(stdin);
        printf("vertexlist 第%d項是V",n);
        scanf("%d",&(g->adjlist[n].vertex)); //取值範圍爲0-65535
        g->adjlist[n].weight = 0;
        g->adjlist[n].FirstEdge = NULL;
    }
    printf("創建頂點表完成!\n");

    //*****************************************************************
    EdgeNode * p = NULL;
    printf("\n開始創建邊表edgelist\n");
    int i,j;
    for(n=0; n<g->EdgeNum; n++)
    {
        fflush(stdin);
        printf("請輸入邊(Vi,Vj)的頂點序號:");
        scanf("%d,%d",&i,&j);
        if(i<0 || j<0||i>(g->VertexNum)||j>(g->VertexNum))
        {
            printf("輸入的值存在非法,操作失敗!\n");
            return -1;
        }
        //在g->adjlist[i]處建立與j的關係
        p = (EdgeNode *)malloc(sizeof(EdgeNode));
        if(p==NULL)
        {
            printf("初始化結構體EdgeNode變量p失敗");
            return -1;
        }
        p->adjVertex = j;
        p->nextNode = g->adjlist[i].FirstEdge;
        g->adjlist[i].FirstEdge = p;

        //在g->adjlist[j]處建立與i的關係
        p = (EdgeNode *)malloc(sizeof(EdgeNode));
        if(p==NULL)
        {
            printf("初始化結構體EdgeNode變量p失敗");
            return -1;
        }
        p->adjVertex = i;
        p->nextNode = g->adjlist[j].FirstEdge;
        g->adjlist[j].FirstEdge = p;
    }
    printf("創建邊表完成!\n");
    return 0;
}

//輸出圖結構
void Output_ALGraph(ALGraph *g)
{
   printf("\n鄰接表輸出如下: \n");
   EdgeNode  * p;
   int n;
   for(n=0 ; n<g->VertexNum ; n++)
   {
       printf("%d ",g->adjlist[n].vertex);//輸出頂點值
        p = g->adjlist[n].FirstEdge;
        while(p!=NULL)
        {
            printf("->");
            printf("%d ",p->adjVertex);
            p = p->nextNode;
        }
        printf("\n");
   }
}

我們最重要的main方法

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

int main(int argc, char *arg[])
{
	printf("嘗試將一個無向圖轉爲一個鄰接表!\n\n");
	int ret;
	ALGraph *g = NULL;
	ret = ALGraph_init(&g);//初始化鄰接表內存區
	if(ret<0)
	{
		perror("初始化圖時發現錯誤:沒有完成初始化操作\n");
		return -1;
	}

	ret  = Create_ALGraph(g);//創建鄰接表
	if(ret<0)
	{
		printf("創建鄰接表失敗!\n");
		return -1;
	}
	Output_ALGraph(g);//輸出鄰接表

    return 0;
}


最後放上程序運行過程,怎麼樣,是不是挺簡單的呢!其實這個並不單單對這個簡單的無向圖,你可以去試一下,如果有什麼改進意見可以在評論告訴我




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章