图的实现:邻接矩阵
为了表现图中顶点之间的关联,我们可以使用邻接矩阵来实现图结构。所谓的邻接矩阵,就是一个反应边与边之间联系的二维数组。这个二维数组我们用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(取最小权值或最大权值)。
下面给出一个实例
类定义
- #include<iostream>
- #include<iomanip>
- using namespace std;
- //最大权值
- #define MAXWEIGHT 100
- //用邻接矩阵实现图
- class Graph
- {
- private:
- //是否带权
- bool isWeighted;
- //是否有向
- bool isDirected;
- //顶点数
- int numV;
- //边数
- int numE;
- //邻接矩阵
- int **matrix;
- public:
- /*
- 构造方法
- numV是顶点数,isWeighted是否带权值,isDirected是否有方向
- */
- Graph(int numV, bool isWeighted = false, bool isDirected = false);
- //建图
- void createGraph();
- //析构方法
- ~Graph();
- //获取顶点数
- int getVerNums()
- {return numV;}
- //获取边数
- int getEdgeNums()
- {return numE;}
- //设置指定边的权值
- void setEdgeWeight(int tail, int head, int weight);
- //打印邻接矩阵
- void printAdjacentMatrix();
- //检查输入
- bool check(int i, int j, int w = 1);
- };
- /*
- 构造方法
- numV是顶点数,isWeighted是否带权值,isDirected是否有方向
- */
- Graph::Graph(int numV, bool isWeighted, bool isDirected)
- {
- while (numV <= 0)
- {
- cout << "输入的顶点数不正确!,重新输入 ";
- cin >> numV;
- }
- this->numV = numV;
- this->isWeighted = isWeighted;
- this->isDirected = isDirected;
- matrix = new int*[numV]; //指针数组
- int i, j;
- for (i = 0; i < numV; i++)
- matrix[i] = new int[numV];
- //对图进行初始化
- if (!isWeighted) //无权图
- {
- //所有权值初始化为0
- for (i = 0; i < numV; i++)
- for (j = 0; j < numV; j++)
- matrix[i][j] = 0;
- }
- else //有权图
- {
- //所有权值初始化为最大权值
- for (i = 0; i < numV; i++)
- for (j = 0; j < numV; j++)
- matrix[i][j] = MAXWEIGHT;
- }
- }
- //建图
- void Graph::createGraph()
- {
- cout << "输入边数 ";
- while (cin >> numE && numE < 0)
- cout << "输入有误!,重新输入 ";
- int i, j, w;
- if (!isWeighted) //无权图
- {
- if (!isDirected) //无向图
- {
- cout << "输入每条边的起点和终点:\n";
- for (int k = 0; k < numE; k++)
- {
- cin >> i >> j;
- while (!check(i, j))
- {
- cout << "输入的边不对!重新输入\n";
- cin >> i >> j;
- }
- matrix[i][j] = matrix[j][i] = 1;
- }
- }
- else //有向图
- {
- cout << "输入每条边的起点和终点:\n";
- for (int k = 0; k < numE; k++)
- {
- cin >> i >> j;
- while (!check(i, j))
- {
- cout << "输入的边不对!重新输入\n";
- cin >> i >> j;
- }
- matrix[i][j] = 1;
- }
- }
- }
- else //有权图
- {
- if (!isDirected) //无向图
- {
- cout << "输入每条边的起点、终点和权值:\n";
- for (int k = 0; k < numE; k++)
- {
- cin >> i >> j >> w;
- while (!check(i, j, w))
- {
- cout << "输入的边不对!重新输入\n";
- cin >> i >> j >> w;
- }
- matrix[i][j] = matrix[j][i] = w;
- }
- }
- else //有向图
- {
- cout << "输入每条边的起点、终点和权值:\n";
- for (int k = 0; k < numE; k++)
- {
- cin >> i >> j >> w;
- while (!check(i, j, w))
- {
- cout << "输入的边不对!重新输入\n";
- cin >> i >> j >> w;
- }
- matrix[i][j] = w;
- }
- }
- }
- }
- //析构方法
- Graph::~Graph()
- {
- int i = 0;
- for (i = 0; i < numV; i++)
- delete[] matrix[i];
- delete[]matrix;
- }
- //设置指定边的权值
- void Graph::setEdgeWeight(int tail, int head, int weight)
- {
- if (isWeighted)
- {
- while (!check(tail, head, weight))
- {
- cout << "输入不正确,重新输入边的起点、终点和权值 ";
- cin >> tail >> head >> weight;
- }
- if (isDirected)
- matrix[tail][head] = weight;
- else
- matrix[tail][head] = matrix[head][tail] = weight;
- }
- else
- {
- while (!check(tail, head, 1))
- {
- cout << "输入不正确,重新输入边的起点、终点 ";
- cin >> tail >> head;
- }
- if (isDirected)
- matrix[tail][head] = 1-matrix[tail][head];
- else
- matrix[tail][head] = matrix[head][tail] = 1 - matrix[tail][head];
- }
- }
- //输入检查
- bool Graph::check(int i, int j, int w)
- {
- if (i >= 0 && i < numV && j >= 0 && j < numV && w > 0 && w <= MAXWEIGHT)
- return true;
- else
- return false;
- }
- //打印邻接矩阵
- void Graph::printAdjacentMatrix()
- {
- int i, j;
- cout.setf(ios::left);
- cout << setw(4) << " ";
- for (i = 0; i < numV; i++)
- cout << setw(4) << i;
- cout << endl;
- for (i = 0; i < numV; i++)
- {
- cout << setw(4) << i;
- for (j = 0; j < numV; j++)
- cout << setw(4) << matrix[i][j];
- cout << endl;
- }
- }
- int main()
- {
- cout << "******使用邻接矩阵实现图结构***by David***" << endl;
- bool isDirected, isWeighted;
- int numV;
- cout << "建图" << endl;
- cout << "输入顶点数 ";
- cin >> numV;
- cout << "边是否带权值,0(不带) or 1(带) ";
- cin >> isWeighted;
- cout << "是否是有向图,0(无向) or 1(有向) ";
- cin >> isDirected;
- Graph graph(numV, isWeighted, isDirected);
- cout << "这是一个";
- isDirected ? cout << "有向、" : cout << "无向、";
- isWeighted ? cout << "有权图" << endl : cout << "无权图" << endl;
- graph.createGraph();
- cout << "打印邻接矩阵" << endl;
- graph.printAdjacentMatrix();
- cout << endl;
- int tail, head, weight;
- cout << "修改指定边的权值" << endl;
- if (isWeighted) //针对有权图
- {
- cout << "输入边的起点、终点和权值 ";
- cin >> tail >> head >> weight;
- graph.setEdgeWeight(tail, head, weight);
- }
- else //针对无权图
- {
- cout << "输入边的起点、终点 ";
- cin >> tail >> head;
- graph.setEdgeWeight(tail, head, 1);
- }
- cout << "修改成功!" << endl;
- cout << "打印邻接矩阵" << endl;
- graph.printAdjacentMatrix();
- system("pause");
- return 0;
- }
实例一
实例二
完整代码下载:图的实现:邻接矩阵