点结构
class Node {
public:
int val;
int in;
int out;
vector<Node*> nexts;
vector<Edge*> edges;
Node(int val) {
this->val = val;
this->in = 0;
this->out = 0;
nexts = vector<Node>();
edges = vector<Edge>();
}
};
边结构
class Edge {
public:
int weight;
Node *from;
Node *to;
Edge(int weight, Node *from, Node *to) {
this->weight = weight;
this->from = from;
this->to = to;
}
};
图结构
class Graph {
public:
unordered_map<int, Node*> nodes;
set<Edge*> edges;
Graph() {
nodes = unordered_map<int, Node*>();
edges = set<Edge*>();
}
};
图构建
class GraphGenerator {
public:
static Graph createGraph(vector<vector<int>> matrix) {
Graph graph = Graph();
for (int i = 0; i < matrix.size(); i++) {
int weight = matrix[i][0];
int from = matrix[i][1];
int to = matrix[i][2];
if (graph.nodes.find(from) == graph.nodes.end()) {
graph.nodes[from] = new Node(from);
}
if (graph.nodes.find(to) == graph.nodes.end()) {
graph.nodes[to] = new Node(to);
}
Node *fromNode = graph.nodes[from];
Node *toNode = graph.nodes[to];
Edge *edge = new Edge(weight, fromNode, toNode);
fromNode->nexts.push_back(toNode);
fromNode->edges.push_back(edge);
fromNode->out++;
toNode->in++;
graph.edges.insert(edge);
}
return graph;
}
};
遍历
因为图可能有环,那么节点可能会重复放入,所以引入STL 中的set 做去重。避免重复放入已遍历的点。
1. 广度优先遍历:利用队列
static void BFS(Node *node) {
if (node == nullptr)
return;
queue<Node *> nqueue;
set<Node *> nset;
nqueue.push(node);
nset.insert(node);
while (!nqueue.empty()) {
Node *cur = nqueue.front();
nqueue.pop();
cout << cur->val << " ";
for (Node *next : cur->nexts) {
if (nset.find(next) == nset.end()) {
nset.insert(next);
nqueue.push(next);
}
}
}
}
2. 深度优先遍历:利用栈
栈里保存的就是从根节点(出发节点)到此节点的路径。
static void DFS(Node *node) {
if (node == nullptr)
return;
stack<Node *> nstack;
set<Node *> nset;
nstack.push(node);
nset.insert(node);
cout << node->val << " ";
while (!nstack.empty()) {
Node *cur = nstack.top();
nstack.pop();
for (Node *next : cur->nexts) {
if (nset.find(next) == nset.end()) {
nstack.push(cur);
nstack.push(next);
nset.insert(next);
cout << next->val << " ";
break;
}
}
}
}
|