C++算法從入門到放棄-無向圖(1)


April 8, 2016

API

class Graph
{
private:
int _v;
int _e;
std::map<int, std::vector<int>> adjMartix;
public:
using Iterator = std::map<int, std::vector<int>>::iterator;
using Const_Iterator = std::map<int, std::vector<int>>::const_iterator;

Graph() = delete;
Graph(int V):_v(V), _e(0)
{
std::vector<int> temp;
for(int i = 0; i < V; ++i){
this->adjMartix.insert(std::pair<int, std::vector<int>>(i, temp));
}

}

Graph(const Graph& other);
Graph& operator=(const Graph& other);

int V() { return _e; }
int E() { return _e; }
void addEdge(int v, int w);
std::vector<int> adj(int v);

int degree(int v);
int maxDegree();
double avgDegree();
int numberOfselfLoops();
std::string toString(std::ostream& os);
};

圖的表示

  • 鄰接矩陣。不能滿足存儲平行邊的需求,放棄。
bool edge[M][N];
  • 邊的數組。如果要找出和某一頂點相鄰的所有頂點那么就要遍整個數組,放棄。
struct Edge
{
int v;
int w;
};
std::vector<Edge> allEdge;
  • 鄰接表數組滿足需求而且空間要求僅為頂點數的兩倍(不考慮順序容器的開銷)。
std::map<int,std::vector<int>> allEdge;

圖的數據結構

使用鄰接表數組表示的圖有如下特點:

  • 使用的空間和V+E成正比
  • 添加一條邊所需要的時間為常數
  • 遍歷頂點v的所有相鄰頂點所需的時間和v的度數成正比(處理每個相鄰頂點所需要的時間為常數)

實現

Graph::Graph(const Graph & other)
{
this->_v = other._v;
this->_e = other._e;
this->adjMartix = other.adjMartix;
}

Graph & Graph::operator=(const Graph & other)
{
this->_v = other._v;
this->_e = other._e;
this->adjMartix = other.adjMartix;
return *this;
}

void Graph::addEdge(int v, int w)
{
Graph::Iterator it = this->adjMartix.find(v);
(*it).second.push_back(w);
++(this->_e);
}

std::vector<int> Graph::adj(int v)
{
return (this->adjMartix).find(v)->second;
}

int Graph::degree(int v)
{
Graph::Const_Iterator cit = this->adjMartix.find(v);
return (*cit).second.size();
}

int Graph::maxDegree()
{
unsigned max = 0;
for each (auto var in this->adjMartix)
{
if(var.second.size() > max)
max = var.second.size();
}
return max;
}

double Graph::avgDegree()
{
return E() / V()*2.0;
}

int Graph::numberOfselfLoops()
{
int count = 0;
for(int v = 0; v < V(); v++){
for each (auto var in adj(v))
{
if(v == var)
++count;
}
}
return count / 2;
}

std::string Graph::toString(std::ostream& os)
{
std::stringstream ss;
ss << this->_v << " vertices. " << this->_e << " edges\n";
for(int v = 0; v < (this->_v); ++v){
ss << v << ": ";
for each (auto var in this->adj(v))
{
ss << var << " ";
}
ss << "\n";
}
os << ss.str();
return ss.str();
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com