图的邻接矩阵表示法

  图常用的存储方法又邻接表表示法以及邻接矩阵表示法,邻接表适合稀疏矩阵的存储,但是缺点是稍微复杂一点,并且插入操作或者说更新图的操作实际上是比较复杂的,而邻接矩阵更加简单,再存储密集矩阵的时候更加合适,下面使用c++实现一个简单的邻接矩阵。

  由于图一般简单的分为几种:1. 无向图 2.有向图 3.带权无向图 4.带权有向图  下面可以构造的时候分别选择这几种方式来实现:

  下面所提到的VType表示的是顶点的类型,一般设置成char或者string用于表示比较合适,ArcType表示的是弧的值类型,对于无权图用0,1分别表示非邻接以及邻接,而有全权图表示权重大小。

  所有的private数据如下所示:

  

1     struct ArcCell{
2         ArcType adj; //顶点对间关系类型,无权图为0或者1,表明相邻或者是不相邻,有权图代表的就是权值的大小
3     };
4     VType *vvec; //用于表示顶点的信息,例如char或者string等
5     ArcCell ** arcs; //邻接矩阵
6     int vecNum; //顶点数目
7     int arcNum; //弧数目
8     GraphKind kind; //图的种类,非别可以为带权有向图,无向图,不带权有向,无向图。

  default constructor:

1     Graph(int _vexNum = 0, GraphKind _kind = DG) :
2         vecNum(_vexNum), arcNum(0), kind(_kind)
3     {
4         vvec = new VType[vecNum];
5         arcs = new ArcCell *[vecNum];
6         for (int i = 0; i < vecNum; ++i){
7             arcs[i] = new ArcCell[vecNum];
8         }
9     }

  destructor是non-trivial的,实际还是需要自己写一个的,代码如下:

1     ~Graph()
2     {
3         for (int i = 0; i < vecNum; ++i){
4             delete[] arcs[i];
5         }
6         delete[] arcs;
7         delete[] vvec;
8     }

  下面是初始化所有的顶点信息:

 1     void Init()
 2     {
 3         cout << "请输入每个顶点的关键字:" << endl;
 4         VType val;
 5         for (int i = 0; i < vecNum; ++i){
 6             cin >> vvec[i];
 7         }
 8         ArcCell ac;
 9         ac.adj = 0;
10         for (int i = 0; i < vecNum; ++i){
11             for (int j = 0; j < vecNum; ++j){
12                 arcs[i][j] = ac;
13             }
14         }
15     }

  下面是根据不同类型来进行图的创建:

  有向图:

 1     void createDG()
 2     {
 3         Init();
 4         int vhead, vtail;
 5         cout << " 请依次输入每条边的开始节点以及结束结点: " << endl;
 6         while (cin >> vhead >> vtail){
 7             arcNum++;
 8             arcs[vhead][vtail].adj = 1;
 9         }
10     }

  带权有向图:

 1     void createWDG()
 2     {
 3         Init();
 4         int vhead, vtail;
 5         ArcType w;
 6         cout << " 请输入每条弧的开始顶点,结束顶点以及权值: " << endl;
 7         while (cin >> vhead >> vtail >> w){
 8             arcNum++;
 9             arcs[vhead][vtail].adj = w;
10         }
11     }

  无向图:

 1     void createUDG()
 2     {
 3         Init();
 4         int vhead, vtail;
 5         cout << "请输入每条弧的开始顶点,结束顶点: " << endl;
 6         while (cin >> vhead >> vtail){
 7             arcNum+=2;
 8             arcs[vhead][vtail].adj = 1;
 9             arcs[vtail][vhead].adj = 1;
10         }
11     }

  带权无向图:

 1     void createWUDG()
 2     {
 3         Init();
 4         int vhead, vtail;
 5         ArcType w;
 6         cout << "请输入每条弧的开始顶点,结束顶点以及弧的权重(总共的顶点数为: " << vecNum << ".)" << endl;
 7         while (cin >> vhead >> vtail >> w){
 8             arcNum+=2;
 9             arcs[vhead][vtail].adj = w;
10             arcs[vtail][vhead].adj = w;
11         }
12     }

  图的显示部分:

 1     void displayGraph()
 2     {
 3         cout << "顶点的总数为: " << vecNum << "个。" << endl;
 4         cout << "弧的总数为: " << arcNum << "条。" << endl;
 5         for (int i = 0; i < vecNum; ++i){
 6             cout << "" << i + 1 << "个顶点为" << vvec[i]
 7             << ",相邻的边为: ";
 8             for (int j = 0; j < vecNum; ++j){
 9                 if (arcs[i][j].adj != 0){
10                     cout << ", (" << arcs[i][j].adj << ", " << vvec[j] << ")";
11                  }
12             }
13             cout << endl;
14         }
15     }

大致上就是这样,有时间再来写一下图的dfs,bfs以及邻接链表表示法,下面贴一张生成图的截图:

posted @ 2016-01-15 16:04  eversliver  阅读(1894)  评论(0编辑  收藏  举报