我必须使用图形在c ++上实现WWW的模拟,其中节点是网页,有向边是URL。
在学校,在我们的水平上,我们仍然从面向对象编程开始,所以他们建议使用邻接列表和邻接矩阵来实现,但我不喜欢它们,因为它们是记忆怪物并且非常有限。
问题:
你能提出另一种数据结构(最好是面向对象的东西),它使用指针(作为边缘)到其他节点,我可以动态生成尽可能多的边缘吗?
我已经读过这篇文章,但我找不到任何有用的信息: Object Oriented implementation of graph data structures
答案 0 :(得分:2)
老实说,只想在一个数据结构中表示这一点,结果会非常低效。实际上,您有一个较小的域名注册商列表,提供查找。比单个哑图更精确的是:
#include <iostream>
#include <memory>
#include <map>
#include <vector>
#include <string>
#include <set>
class Webpage;
class Registrar : public std::enable_shared_from_this<Registrar> {
public:
std::shared_ptr<Webpage> resolve(const std::string &url);
private:
std::map<std::string, std::shared_ptr<Webpage>> pages;
};
class Webpage {
public:
Webpage(std::shared_ptr<Registrar> registrar, const std::string &url) :
registrar(registrar),
url(url){
}
std::shared_ptr<Webpage> addLink(const std::string &url){
links.push_back(url);
return registrar->resolve(url);
}
std::vector<std::shared_ptr<Webpage>> resolvePageLinks(){
std::vector<std::shared_ptr<Webpage>> pages;
for (auto &linkUrl : links){
pages.push_back(registrar->resolve(linkUrl));
}
return pages;
}
std::string getUrl() const{
return url;
}
private:
std::string url;
std::shared_ptr<Registrar> registrar;
std::vector<std::string> links;
};
std::shared_ptr<Webpage> Registrar::resolve(const std::string &url){
auto found = pages.find(url);
if (found != pages.end()){
return found->second;
}
else{
auto webpage = std::make_shared<Webpage>(shared_from_this(), url);
pages.insert({url, webpage});
return webpage;
}
}
void printPageHierarchy(std::shared_ptr<Webpage> current, int depth, std::set<std::shared_ptr<Webpage>> &visited){
std::cout << std::string(3*depth, ' ');
std::cout << current->getUrl() << std::endl;
if (visited.find(current) == visited.end()){
visited.insert(current);
++depth;
for (auto page : current->resolvePageLinks()){
printPageHierarchy(page, depth, visited);
}
}else{
std::cout << std::string(3*depth, ' ');
std::cout << "..." << std::endl;
}
}
void printPageHierarchy(std::shared_ptr<Webpage> current){
std::set<std::shared_ptr<Webpage>> visited;
printPageHierarchy(current, 0, visited);
}
int main(){
auto registrar = std::make_shared<Registrar>();
auto site1 = registrar->resolve("site1.com");
site1->addLink("site2.com");
site1->addLink("site3.com")->addLink("site4.com")->addLink("site1.com");
std::cout << "From site1.com:" << std::endl;
printPageHierarchy(site1);
std::cout << "_____________\nFrom site3.com:" << std::endl;
printPageHierarchy(registrar->resolve("site3.com"));
}
这非常简单,显然很少。你的问题让你有点不清楚你的要求究竟是什么。