图的储存方式之邻接矩阵

时间:2023-02-03 20:48:32
                                                                                       图的存储结构之邻接矩阵

图是一种复杂的数据结构,表现在不仅各个顶点的度可以相差很多,而且顶点的逻辑关系也错综复杂。从图的定义可知,一个图包含两方面的信息:顶点的信息以及描述顶点之间关系的信息。

 

邻接矩阵:

也称为数组表示法,其方法是用一个一维数组存储顶点信息,用二维数组存储边的信息,这个二维数组称为邻接矩阵。

                       Arc[i][j]=1, if (vi,vj)属于E

Arc[i][j]=0, if (vi,vj)不属于E

若为网图

Arc[i][j]=wij, if (vi,vj)属于E

Arc[i][j]=0, if i=j

Arc[i][j]=∞, 否则

其中,wij表示权值,∞表示一个计算机允许的、大于所有边的权值的数

显然,无向图的邻接矩阵一定是对称矩阵,有向图的邻接矩阵则不一定对称

优点:在邻接矩阵中容易解决下列问题:

1.      对于无向图,顶点的度等于邻接矩阵第i行或第i列的非零元素的个数。对于有向图,顶点i的出度为第i行的非零元素的个数,入度为第i列非零元素的个数

2.      要判断i和j之间是否存在边,仅需要判断邻接矩阵中相应的元素Arc[i][j]

3.      要找顶点的所有邻接点,可以依次判断顶点与其他顶点是否有边或弧

算法:

const int maxsize=10;

templete <class datatype>

class mGraph

{

public:

           mGraph(datatypea[],int n,int e);//constructor, n nodes, e edges

           ~mGraph(){};                //empty destructor

           void DFSTraverse(intv);        //depth-first travel

           void BFSTraverse(intv);        //breadth-first travel

private:

           datatypevertex[maxsize];      //node array

           intarc[maxsize][maxsize];      //edge array

           int vertexnum,arcnum;        //number of nodes andedges

                   

 } ;

构造函数:

Pseudocode:

1.      确定图的顶点个数和边的个数

2.      输入顶点信息储存在一维数组中

3.      初始化邻接矩阵

4.      依次输入每条边储存在邻接矩阵中

(1)      输入两个顶点i,j

(2)      Arc[i][j]=1,Arc[j][i]=1;

C++:

templete <class datatype>

 mGraph<datatype>::mGraph(datatypea[],int n,int e)

 {

        vertexnum=n;arcnum=e;

        for(int i=0;i<vertexnum;i++)

        {

                 vertex[i]=a[i];

          }

         for(inti=0;i<vertexnum;i++)

         for(intj=0;j<vertexnum;j++)

         {

                   arc[i][j]=0;

         }

         for(inti=0;i<arcnum;i++)

    {

             cin>>i>>j;

             arc[i][j]=1;

             arc[j][i]=1;

    }        

 }

深度优先遍历:(伪代码已经在前面的文章中提及,下有链接)http://blog.csdn.net/qq_36642226/article/details/74855911

C++:

templete <class datatype>

 voidmGraph<datatype>::DFSTraverse(int v)

 {

        cout<<vertex[v];

        visited[v]=1;

        for(int j=0;j<vertexnum;j++)

        {

                 if(arc[v][j]==1&&visited[j]==0)

                 DFSTraverse(j);

          }

 }

广度优先遍历:(伪代码已经在前面的文章中提及,下有链接)http://blog.csdn.net/qq_36642226/article/details/74855911

C++:

templete <class datatype>

void mGraph<datatype>::BFSTraverse(int v)

{

         front=rear=-1;

        

         cout<<vertex[v];

         visited[v]=1;

         Q[++rear]=v;//queue

         while(front!=rear)

         {

                   v=Q[++front];

                   for(intj=0;j<vertexnum;j++)

                   if(arc[v][j]==1&&visited[j]==00)

                   {

                            cout<<vertex[j];

                            visited[j]=1;

                            Q[++rear]=j;

                   }

         }

        

}