图的表示
邻接矩阵,邻接表
目标:在一种图的表示上实现图的所有算法,在实际遇到,就只需要考虑怎么从一种图的表示转换到我们的表示上
struct Node {
int value;//类型根据实际变化
int in;//入度
int out;//出度
vector<Node*> nexts;//当前节点的邻居有哪些,在有向图中,由当前节点指向他们
vector<Edge*> edges;//属于当前节点的边有哪些,由当前节点指向其他
Node(int value){
this->value = value;
in = 0;
out = 0;
}
};
struct Edge {
int weight;
Node from;
Node to;
Edge(int weight,Node from,Node to){
this->weight = weight;
this->from = from;
this->to = to;
}
};
struct Graph {
unordered_map<int, Node*> nodes;
unordered_set<Edge*> edges;
};
图的宽度优先遍历
//利用队列
//从源节点开始依次按照宽度进入队列,然后弹出
//每弹出一个点,把该点的邻居加入队列
//直到队列变空
void bfs(Node* node){
if(node == nullptr) return;
queue<Node*> que;
unordered_set<Node*> set;//记录已经遍历的点
que.push(node);
set.emplace(node);
while(!que.empty()){
Node* cur = que.front();
que.pop();
//处理该节点
for(auto i : cur->nexts){
if(set.find(i) != set.end()) continue;
que.push(i);
set.emplace(i);
}
}
}
深度优先遍历
//1,利用栈实现
//2,从源节点按照深度放入栈,然后弹出
//3,每弹出一个点,把该点的下一个没有进栈的邻节点放入栈,若找到可以入栈的邻节点,则把该节点和该邻居依次压入栈。若不存在,则不在入栈
//4,直到栈为空
void dfs(Node* node){
if(node == nullptr) return;
stack<Node> sta;
unordered_set<Node> set;
sta.push(node);
set.emplace(node);
print(cur->val);
while(!sta.empty()){
Node* cur = sta.pop();
for(auto i : cur->nexts){
if(set.find(i) == set.end()){
sta.push(cur);
sta.push(i);
set.emplace(i);
print(cur->val);
break;
}
}
}
}
拓扑排序算法
//例子,现在你需要选课,假设总共有10门课,但是课程之间有依赖关系,一些课只有在选了某些课的情况下才能选,现在就需要你给出一个选课的顺序,使得所有课都可以选。
//不管题上顺序怎么样,都可以转成图的存储。
vector<Node*> res;
vector<Node*> sortedtopology(Graph graph){
queue<Node*> zeroque;//记录入度为零的节点
unordered_map<Node*,int> map;//记录各个节点的入度
for(auto i:graph.nodes){
map.emplace(i,i.in);
if(map[i] == 0)
zeroque.push(i);
}
while(!zeroque.empty()){
Node* node = zeroque.front();
zeroque.pop();
res.push_back(node);
for(auto i : node->nexts){
map[i]--;
if(map[i]==0)
zeroque.push(i);
}
}
return res;
}
无向图上的最小生成树实现:
//K算法
//将边按照权重排序
//每次加入一个边,若不会形成环,则加上,否则,不加入该边
//难点在于怎么判断当前有没有生成环 --并查集实现