数据结构:图的实现--邻接矩阵

图的实现:邻接矩阵

为了表现图中顶点之间的关联,我们可以使用邻接矩阵来实现图结构。所谓的邻接矩阵,就是一个反应边与边之间联系的二维数组。这个二维数组我们用matrix[numV][numV]表示,其中numV是顶点数。

对于无权图

若顶点Vi和Vj之间有边,则matrix[Vi][Vj]=1;否则matrix[Vi][Vj]=0。

对于有权图

若顶点Vi和Vj之间有边,且权值为weight,则matrix[Vi][Vj]=weight;否则matrix[Vi][Vj]=0或MAXWEIGHT(取最小权值或最大权值)。


下面给出一个实例

类定义

[cpp]  view plain copy
  1. #include<iostream>  
  2. #include<iomanip>  
  3. using namespace std;  
  4. //最大权值  
  5. #define MAXWEIGHT 100  
  6. //用邻接矩阵实现图  
  7. class Graph  
  8. {  
  9. private:  
  10.     //是否带权  
  11.     bool isWeighted;  
  12.     //是否有向  
  13.     bool isDirected;  
  14.     //顶点数  
  15.     int numV;  
  16.     //边数  
  17.     int numE;  
  18.     //邻接矩阵  
  19.     int **matrix;  
  20. public:  
  21.     /* 
  22.     构造方法 
  23.     numV是顶点数,isWeighted是否带权值,isDirected是否有方向 
  24.     */  
  25.     Graph(int numV, bool isWeighted = falsebool isDirected = false);  
  26.     //建图  
  27.     void createGraph();  
  28.     //析构方法  
  29.     ~Graph();  
  30.     //获取顶点数  
  31.     int getVerNums()  
  32.     {return numV;}  
  33.     //获取边数  
  34.     int getEdgeNums()  
  35.     {return numE;}  
  36.     //设置指定边的权值  
  37.     void setEdgeWeight(int tail, int head, int weight);  
  38.     //打印邻接矩阵  
  39.     void printAdjacentMatrix();  
  40.     //检查输入  
  41.     bool check(int i, int j, int w = 1);  
  42. };  
类实现

[cpp]  view plain copy
  1. /* 
  2. 构造方法 
  3. numV是顶点数,isWeighted是否带权值,isDirected是否有方向 
  4. */  
  5. Graph::Graph(int numV, bool isWeighted, bool isDirected)  
  6. {  
  7.     while (numV <= 0)  
  8.     {  
  9.         cout << "输入的顶点数不正确!,重新输入 ";  
  10.         cin >> numV;  
  11.     }  
  12.     this->numV = numV;  
  13.     this->isWeighted = isWeighted;  
  14.     this->isDirected = isDirected;  
  15.     matrix = new int*[numV];  //指针数组  
  16.     int i, j;  
  17.     for (i = 0; i < numV; i++)  
  18.         matrix[i] = new int[numV];  
  19.     //对图进行初始化  
  20.     if (!isWeighted)  //无权图  
  21.     {  
  22.         //所有权值初始化为0  
  23.         for (i = 0; i < numV; i++)  
  24.         for (j = 0; j < numV; j++)  
  25.             matrix[i][j] = 0;  
  26.     }  
  27.     else  //有权图  
  28.     {  
  29.         //所有权值初始化为最大权值  
  30.         for (i = 0; i < numV; i++)  
  31.         for (j = 0; j < numV; j++)  
  32.             matrix[i][j] = MAXWEIGHT;  
  33.     }  
  34. }  
  35. //建图  
  36. void Graph::createGraph()  
  37. {  
  38.     cout << "输入边数 ";  
  39.     while (cin >> numE && numE < 0)  
  40.         cout << "输入有误!,重新输入 ";  
  41.   
  42.     int i, j, w;  
  43.     if (!isWeighted)  //无权图  
  44.     {  
  45.         if (!isDirected)  //无向图  
  46.         {  
  47.             cout << "输入每条边的起点和终点:\n";  
  48.             for (int k = 0; k < numE; k++)  
  49.             {  
  50.                 cin >> i >> j;  
  51.                 while (!check(i, j))  
  52.                 {  
  53.                     cout << "输入的边不对!重新输入\n";  
  54.                     cin >> i >> j;  
  55.                 }  
  56.                 matrix[i][j] = matrix[j][i] = 1;  
  57.             }  
  58.         }  
  59.         else  //有向图  
  60.         {  
  61.             cout << "输入每条边的起点和终点:\n";  
  62.             for (int k = 0; k < numE; k++)  
  63.             {  
  64.                 cin >> i >> j;  
  65.                 while (!check(i, j))  
  66.                 {  
  67.                     cout << "输入的边不对!重新输入\n";  
  68.                     cin >> i >> j;  
  69.                 }  
  70.                 matrix[i][j] = 1;  
  71.             }  
  72.         }  
  73.     }  
  74.     else  //有权图  
  75.     {  
  76.         if (!isDirected)   //无向图  
  77.         {  
  78.             cout << "输入每条边的起点、终点和权值:\n";  
  79.             for (int k = 0; k < numE; k++)  
  80.             {  
  81.                 cin >> i >> j >> w;  
  82.                 while (!check(i, j, w))  
  83.                 {  
  84.                     cout << "输入的边不对!重新输入\n";  
  85.                     cin >> i >> j >> w;  
  86.                 }  
  87.                 matrix[i][j] = matrix[j][i] = w;  
  88.             }  
  89.         }  
  90.         else  //有向图  
  91.         {  
  92.             cout << "输入每条边的起点、终点和权值:\n";  
  93.             for (int k = 0; k < numE; k++)  
  94.             {  
  95.                 cin >> i >> j >> w;  
  96.                 while (!check(i, j, w))  
  97.                 {  
  98.                     cout << "输入的边不对!重新输入\n";  
  99.                     cin >> i >> j >> w;  
  100.                 }  
  101.                 matrix[i][j] = w;  
  102.             }  
  103.         }  
  104.     }  
  105. }  
  106. //析构方法  
  107. Graph::~Graph()  
  108. {  
  109.     int i = 0;  
  110.     for (i = 0; i < numV; i++)  
  111.         delete[] matrix[i];  
  112.     delete[]matrix;  
  113. }  
  114. //设置指定边的权值  
  115. void Graph::setEdgeWeight(int tail, int head, int weight)  
  116. {  
  117.     if (isWeighted)  
  118.     {  
  119.         while (!check(tail, head, weight))  
  120.         {  
  121.             cout << "输入不正确,重新输入边的起点、终点和权值 ";  
  122.             cin >> tail >> head >> weight;  
  123.         }  
  124.         if (isDirected)  
  125.             matrix[tail][head] = weight;  
  126.         else  
  127.             matrix[tail][head] = matrix[head][tail] = weight;  
  128.     }  
  129.     else  
  130.     {  
  131.         while (!check(tail, head, 1))  
  132.         {  
  133.             cout << "输入不正确,重新输入边的起点、终点 ";  
  134.             cin >> tail >> head;  
  135.         }  
  136.         if (isDirected)  
  137.             matrix[tail][head] = 1-matrix[tail][head];  
  138.         else  
  139.             matrix[tail][head] = matrix[head][tail] = 1 - matrix[tail][head];  
  140.     }  
  141. }  
  142. //输入检查  
  143. bool Graph::check(int i, int j, int w)  
  144. {  
  145.     if (i >= 0 && i < numV && j >= 0 && j < numV && w > 0 && w <= MAXWEIGHT)  
  146.         return true;  
  147.     else  
  148.         return false;  
  149. }  
  150. //打印邻接矩阵  
  151. void Graph::printAdjacentMatrix()  
  152. {  
  153.     int i, j;  
  154.     cout.setf(ios::left);  
  155.     cout << setw(4) << " ";  
  156.     for (i = 0; i < numV; i++)  
  157.         cout << setw(4) << i;  
  158.     cout << endl;  
  159.     for (i = 0; i < numV; i++)  
  160.     {  
  161.         cout << setw(4) << i;  
  162.         for (j = 0; j < numV; j++)  
  163.             cout << setw(4) << matrix[i][j];  
  164.         cout << endl;  
  165.     }  
  166. }  
主函数

[cpp]  view plain copy
  1. int main()  
  2. {  
  3.     cout << "******使用邻接矩阵实现图结构***by David***" << endl;  
  4.     bool isDirected, isWeighted;  
  5.     int numV;  
  6.     cout << "建图" << endl;  
  7.     cout << "输入顶点数 ";  
  8.     cin >> numV;  
  9.     cout << "边是否带权值,0(不带) or 1(带) ";  
  10.     cin >> isWeighted;  
  11.     cout << "是否是有向图,0(无向) or 1(有向) ";  
  12.     cin >> isDirected;  
  13.     Graph graph(numV, isWeighted, isDirected);  
  14.     cout << "这是一个";  
  15.     isDirected ? cout << "有向、" : cout << "无向、";  
  16.     isWeighted ? cout << "有权图" << endl : cout << "无权图" << endl;  
  17.     graph.createGraph();  
  18.     cout << "打印邻接矩阵" << endl;  
  19.     graph.printAdjacentMatrix();  
  20.     cout << endl;  
  21.     int tail, head, weight;  
  22.     cout << "修改指定边的权值" << endl;  
  23.     if (isWeighted)  //针对有权图  
  24.     {  
  25.         cout << "输入边的起点、终点和权值 ";  
  26.         cin >> tail >> head >> weight;  
  27.         graph.setEdgeWeight(tail, head, weight);  
  28.     }  
  29.     else  //针对无权图  
  30.     {  
  31.         cout << "输入边的起点、终点 ";  
  32.         cin >> tail >> head;  
  33.         graph.setEdgeWeight(tail, head, 1);  
  34.     }  
  35.     cout << "修改成功!" << endl;  
  36.     cout << "打印邻接矩阵" << endl;  
  37.     graph.printAdjacentMatrix();  
  38.     system("pause");  
  39.     return 0;  
  40. }  
运行

实例一


实例二




完整代码下载:图的实现:邻接矩阵


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值