Files
Data-Structure/Graph/adjacencyMatrix/adjacencyMatrix.h
2025-08-28 13:45:08 +08:00

158 lines
4.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
这里我们规定顶点从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 << " ";
}