diff --git a/cpp/graph.hpp b/cpp/graph.hpp index 976589eda84764818941fa30e876f41fdf9fe8c2..4c85bc4c450b59a25961877987211b4bb3e511e7 100644 --- a/cpp/graph.hpp +++ b/cpp/graph.hpp @@ -32,6 +32,8 @@ typedef std::vector DiDegreeSequence; template< class RandomIt, class Compare > void insertionSort( RandomIt first, RandomIt last, Compare comp ) { + if (first == last) + return; for (RandomIt next = first;;) { RandomIt a = next; next++; @@ -39,16 +41,17 @@ void insertionSort( RandomIt first, RandomIt last, Compare comp ) { break; RandomIt b = next; auto newvalue = *next; - // next - // 1 2 3 4 5 6 4 - // a b - // a b - // a b - // a b + // next + // 1 2 3 4 5 6 4 + // a b + // 1 2 3 4 5 x 6 + // a b + // 1 2 3 4 x 5 6 + // a b + // 1 2 3 4 4 5 6 while (b != first && comp(newvalue, *a)) { // if newvalue < *a *b = *a; - a--; - b--; + b = a--; } *b = newvalue; } @@ -86,7 +89,7 @@ class Graph { // When the degree sequence is not graphics, the Graph can be // in any state, it is not neccesarily empty - bool createFromDegreeSequence(const DegreeSequence &d) { + bool createFromDegreeSequence(const DegreeSequence &d, bool slowSort = false) { // Havel-Hakimi algorithm // Based on Erdos-Gallai theorem @@ -102,16 +105,21 @@ class Graph { // Clear the graph reset(n); + // First use general sorting algorithm + std::sort( + degrees.begin(), degrees.end(), + [](const auto &p1, const auto &p2) { return p1.first < p2.first; }); + while (!degrees.empty()) { - insertionSort(degrees.begin(), degrees.end(), - [](const auto& p1, const auto& p2) { - return p1.first < p2.first; - }); // Highest degree is at back of the vector // Take it out unsigned int degree = degrees.back().first; unsigned int u = degrees.back().second; degrees.pop_back(); + // In the end, all remaining degrees are zero + if (degree == 0) { + break; + } if (degree > degrees.size()) { return false; } @@ -124,6 +132,20 @@ class Graph { rit->first--; ++rit; } + // To compare influence of sorting methods + if (slowSort) { + // Re-sort using general sort + std::sort(degrees.begin(), degrees.end(), + [](const auto &p1, const auto &p2) { + return p1.first < p2.first; + }); + } else { + // Re-sort using insertion sort + insertionSort(degrees.begin(), degrees.end(), + [](const auto &p1, const auto &p2) { + return p1.first < p2.first; + }); + } } return true; }