158 lines
4.0 KiB
C++
158 lines
4.0 KiB
C++
/*
|
||
这里我们规定顶点从0开始,如果从1开始,则代码需要通过(_v - 1)的方式修改进入matrix的方式
|
||
*/
|
||
#pragma once
|
||
#include <iostream>
|
||
#include "graph.h"
|
||
#include "vertexIterator.h"
|
||
#include <deque>
|
||
#include <limits>
|
||
#include <vector>
|
||
template <class T>
|
||
class adjacencyMatrix : public Graph<T> {
|
||
private:
|
||
int v;
|
||
int e;
|
||
std::vector<std::vector<T>> matrix;
|
||
std::vector<bool> reach;
|
||
static constexpr T INF = std::numeric_limits<T>::infinity(); // 非常重要:-| 无边时的值
|
||
//如果是static const类内声明,要类外定义
|
||
|
||
//关注:迭代器iterator在类里面初始化,嵌套类
|
||
class VertexIteratorImpl : public vertexIterator<T> {
|
||
private:
|
||
const std::vector<T>& neighbors; // 当前节点的邻居行
|
||
int current; // 当前邻居索引
|
||
int n; // 矩阵维度
|
||
const T INF; // 无边标记
|
||
|
||
public:
|
||
VertexIteratorImpl(const std::vector<T>& row, int size, T inf)
|
||
: neighbors(row), current(0), n(size), INF(inf) {
|
||
}
|
||
|
||
int next() override {
|
||
while (current < n && neighbors[current] == INF) {
|
||
++current;
|
||
}
|
||
if (current < n) {
|
||
return current++;
|
||
}
|
||
return -1; // 没有更多邻居
|
||
}
|
||
|
||
bool hasNext() const override {
|
||
int temp = current;
|
||
while (temp < n && neighbors[temp] == INF) {
|
||
++temp;
|
||
}
|
||
return temp < n;
|
||
}
|
||
};
|
||
|
||
public:
|
||
adjacencyMatrix(int _v): v(_v), e(0) {
|
||
//很重要,先把所有边置零
|
||
matrix.assign(_v, std::vector<T>(_v, INF));
|
||
reach.assign(_v, false);
|
||
}
|
||
~adjacencyMatrix() override {}
|
||
bool validateV(int _v) const {
|
||
return _v >= 0 && _v < v;
|
||
}
|
||
int numberOfVertices() const override { return v; }
|
||
int numberOfEdges() const override { return e; }
|
||
bool existsEdge(int _a, int _b) const override {
|
||
//有向图,特指a->b
|
||
if (!validateV(_a) || !validateV(_b)) return false;
|
||
return matrix[_a][_b] != INF;
|
||
}
|
||
void insertEdge(edge<T>* _e) override {
|
||
if (!_e) return;
|
||
if (!validateV(_e->from) || !validateV(_e->to)) return;
|
||
matrix[_e->from][_e->to] = _e->weight;
|
||
e++;
|
||
}
|
||
void eraseEdge(int _a, int _b){
|
||
if (!validateV(_a) || !validateV(_b)) return;
|
||
matrix[_a][_b] = INF;
|
||
e--;
|
||
}
|
||
//关注环
|
||
int degree(int _v) const override {
|
||
return inDegree(_v) + outDegree(_v);
|
||
}
|
||
int inDegree(int _v) const override {
|
||
int js = 0;
|
||
for (int i = 0;i < v; i++) {
|
||
if (matrix[i][_v] != INF) js++;
|
||
}
|
||
return js;
|
||
}
|
||
int outDegree(int _v) const {
|
||
int js = 0;
|
||
for (auto x : matrix[_v]) {
|
||
if (x != INF) js++;
|
||
}
|
||
return js;
|
||
}
|
||
// 返回节点u的邻居迭代器
|
||
vertexIterator<T>* iterator(int _v) override {
|
||
validateV(_v);
|
||
return new VertexIteratorImpl(matrix[_v], v, INF);
|
||
}
|
||
// 是否为有向图
|
||
bool directed() const override {
|
||
return true; // 有向图
|
||
}
|
||
|
||
// 是否为加权图
|
||
bool weighted() const override {
|
||
return true; // 加权图
|
||
}
|
||
|
||
void bfs(int _v);
|
||
void dfs(int _v);
|
||
};
|
||
|
||
template<class T>
|
||
inline void adjacencyMatrix<T>::bfs(int _v)
|
||
{
|
||
std::deque<int> arr;
|
||
arr.push_back(_v);
|
||
std::vector<bool> visited;
|
||
visited.assign(v, false);
|
||
visited[_v] = true;
|
||
|
||
while (!arr.empty()) {
|
||
int u = arr.front();
|
||
std::cout << u << " ";
|
||
arr.pop_front();
|
||
|
||
for (int i = 0; i < v; i++) {
|
||
if (matrix[u][i] != INF && !visited[i]) {
|
||
arr.push_back(i);
|
||
visited[i] = true;
|
||
}
|
||
}
|
||
}
|
||
std::cout << std::endl;
|
||
}
|
||
|
||
template<class T>
|
||
inline void adjacencyMatrix<T>::dfs(int _v)
|
||
{
|
||
if (!validateV(_v)) return;
|
||
if (reach.at(_v) == true) return;
|
||
reach.at(_v) = true;
|
||
|
||
std::cout << _v << " ";
|
||
for (int i = 0; i < v; i++) {
|
||
if (matrix[_v][i] != INF && reach.at(i) == false) {
|
||
dfs(i);
|
||
}
|
||
}
|
||
//后序输出std::cout << _v << " ";
|
||
}
|
||
|