Adjacency matrix on undirected graph Please review my Adjacency Matrix class based on this code.


Since I use std::vector to create the matrix, I would like to store as many nodes as possible. Is it OK to use std::size_t all over the code?
Are using 1 for connected and 0 for not connected a bad idea?




class AdjMatrix {
public:
    AdjMatrix(const std::size_t&amp; vertsize);
    std::size_t Vertices() const;
    std::size_t Edges() const;
    void addEdge(const std::size_t&amp; a, const std::size_t&amp; b);
    std::size_t degree(const std::size_t&amp; v) const;
    std::size_t maxDegree() const;
    std::size_t minDegree() const;
private:
    std::size_t vertices;
    std::size_t edges;
    std::vector&lt;std::vector&lt;std::size_t&gt;&gt; matrix;
};

AdjMatrix::AdjMatrix(const std::size_t&amp; vertsize) :vertices{vertsize &lt; 0? throw std::out_of_range{"necgative values"} : vertsize}, edges{0}, matrix{vertsize} {
    for (auto&amp; v : matrix) {
        v.resize(vertsize);
    }
}

std::size_t AdjMatrix::Vertices() const {
    return vertices;
}

std::size_t AdjMatrix::Edges() const {
    return edges;
}

void AdjMatrix::addEdge(const std::size_t&amp; a, const std::size_t&amp; b) {
    if (a &lt; 0 || b &lt; 0) {
        throw std::out_of_range{"negative values"};
    }
    if (matrix[a][b] == 0) {
        edges++;
    }
    matrix[a][b] = 1;
    matrix[b][a] = 1;
}

std::size_t AdjMatrix::degree(const std::size_t&amp; v) const {
    std::size_t d = 0;
    for (std::size_t i = 0; i &lt; matrix[v].size(); ++i) {
        if (matrix[v][i] == 1) {
            d++;
        }
    }
    return d;
}

std::size_t AdjMatrix::maxDegree() const {
    std::size_t max = 0;
    for (std::size_t i = 0; i &lt; matrix.size(); i++) {
        std::size_t d = degree(i);
        max = d &gt; max ? d : max;
    }
    return max;
}

std::size_t AdjMatrix::minDegree() const {
    std::size_t min;
    for (std::size_t i = 0; i &lt; matrix.size(); i++) {
        std::size_t d = degree(i);
        if (i == 0) {
            min = d;
        } else {
            min = min &lt; d ? min : d;
        }
    }
    return min;
}


How can I improve this code?
Using std::size_t. You asked:


  Is it ok to use std::size_t all over the code?


I think that's perfectly alright.
Use of const std::size_t

Using const std::size_t for the type of an argument has no advantage over using just std::size_t. It adds unnecessary verbosity. I would change them all to use std::size_t.
Inconsistent member function names.

Function names are better that start with a verb, such as addEdge. However, all other member functions don't follow that naming convention.

I would recommend the following changes:

  Vertices  -&gt; getNumVertices
  Edges     -&gt; getNumEdges
  degree    -&gt; getDegree
  maxDegree -&gt; getMaxDegree
  minDegree -&gt; getMinDegree

Variable names

I think it's more appropriate to use numVertice and  numEdges instead of vertices and edges.
Checking for negative inputs

An object of std::size_t will never have a negative value. It's pointless to check whether an input is negative when it is of type std::size_t. I would recommend removing those checks altogether.
Range checking

In addEdge, you have:

if (a &lt; 0 || b &lt; 0) {
    throw std::out_of_range{"negative values"};
}


The check for negative values is not necessary. However, it is necessary to check whether those are within the upper bound. I would replace that check with:

if (a &gt;= numVertices || b &gt;= numVertices ) {

Better initialization of matrix.

I would change the constructor to:

AdjMatrix::AdjMatrix(std::size_t&amp; vertsize) : numVertices{vertsize},
                                              edges{0},
                                              matrix{vertsize, std::vector&lt;std::size_t&gt;{vertsize, 0}}
{
}

Using std namespace in member function implementations.

If the member functions are implemented in a .cpp file, I would add

using std::size_t;
using std::vector;


in the .cpp file to reduce the amount of typing.
Remove if/else from minDegree().

Initialize min to std::numeric_limits&lt;std::size_t&gt;::max. Then, you don't need the if/else check. You can replace the lines:

if (i == 0) {
    min = d;
} else {
    min = min &lt; d ? min : d;
}


with 

min = min &lt; d ? min : d;