图
图的节点
//
// Created by Administrator on 2021/8/10.
//
#ifndef C__TEST02_NODE_HPP
#define C__TEST02_NODE_HPP
#include "iostream"
#include <vector>
using namespace std;
class Edge;
class Node {
public:
int value;
int in; //入度
int out; //出度
vector<Node*> nexts; //出度连接的节点
vector<Edge*> nextEdges; //出度连接节点的边长
explicit Node(int value);
};
Node::Node(int value):value(value) {
in = 0;
out = 0;
}
class Edge {
public:
int weight;
Node *from;
Node *to;
Edge(int weight, Node *from, Node *to);
};
Edge::Edge(int weight, Node *from, Node *to) :
weight(weight), from(from), to(to)
{}
#endif //C__TEST02_NODE_HPP
图及相关算法
//
// Created by Administrator on 2021/8/10.
//
#ifndef C__TEST02_GRAPH_HPP
#define C__TEST02_GRAPH_HPP
#include "Node.hpp"
#include "MyHeap.hpp"
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <stack>
#include <list>
using namespace std;
class Graph {
public:
unordered_set<Edge*> edges;
unordered_map<int, Node*> nodes;
explicit Graph(vector<vector<int>> &matrix){
creatGraph(matrix);
}
void creatGraph(vector<vector<int>> &matrix);
void BFS(Node* head);
void DFS(Node* head);
Node* getMinDistanceAndUnuseSelecedNode(
unordered_map<Node*, int> &distanceMap,
unordered_set<Node*> &touchSet);
unordered_map<Node*, int> dijkstral(Node* head);
unordered_map<Node*, int> dijkstral(Node* head, int heapSize);
};
void Graph::creatGraph(vector<vector<int>> &matrix){
for(vector<int> it:matrix){
//获得from和to节点,以及权值
int from = it[0];
int to = it[1];
int weight = it[2];
//如果from节点或者to节点没创建,则创建并记录两个节点
if(nodes.find(from) == nodes.end()){
nodes[from] = new Node(from);
}
if(nodes.find(to) == nodes.end()){
nodes[to] = new Node(to);
}
//获得from和to节点
Node* fromNode = nodes[from];
Node* toNode = nodes[to];
Edge* weightEdge = new Edge(weight, fromNode, toNode);
fromNode->out++;
toNode->in++;
fromNode->nextEdges.push_back(weightEdge);
fromNode->nexts.push_back(toNode);
edges.insert(weightEdge);
}
}
//宽度优先搜索
void Graph::BFS(Node *head){
unordered_set<Node*> hashSet;
queue<Node*> q;
q.push(head);
hashSet.insert(head);
while(!q.empty()){
Node *cur = q.front();
cout<<cur->value<<endl;
q.pop();
for(Node* next:cur->nexts){
if(hashSet.find(next) == hashSet.end()){
q.push(next);
hashSet.insert(next);
}
}
}
}
//广度优先搜索
void Graph::DFS(Node *head) {
stack<Node*> s;
unordered_set<Node*> hashSet;
s.push(head);
hashSet.insert(head);
cout<<head->value<<endl;
while(!s.empty()){
Node* cur = s.top();
s.pop();
for(Node* next:cur->nexts){
if(hashSet.find(next) == hashSet.end()){
s.push(cur);
s.push(next);
cout<<next->value<<endl;
hashSet.insert(next);
break;
}
}
}
}
Node* Graph::getMinDistanceAndUnuseSelecedNode(
unordered_map<Node*, int> &distanceMap,
unordered_set<Node*> &touchSet){
int minDistance = INT_MAX;
Node* minNode = nullptr;
for(auto & it : distanceMap){
Node* distanceNode = it.first;
int distance = it.second;
if(touchSet.find(distanceNode) == touchSet.end() && distance < minDistance){
minDistance = distance;
minNode = distanceNode;
}
}
return minNode;
}
unordered_map<Node*, int> Graph::dijkstral(Node* head){
unordered_map<Node*, int> distanceMap;
unordered_set<Node*> touchSet;
distanceMap[head] = 0;
Node* minNode = getMinDistanceAndUnuseSelecedNode(
distanceMap, touchSet);
while(minNode != nullptr){
//获取当前距离最小的节点的距离
int distance = distanceMap[minNode];
//遍历当前节点的所有边
for(auto edge:minNode->nextEdges){
//取得该边的达到节点
Node* toNode = edge->to;
//如果到达节点没有记录,则记录minNode的距离加边的距离
if(distanceMap.find(toNode) == distanceMap.end()){
distanceMap[toNode] = edge->weight + distance;
}
//如果记录了,比较记录值和上面边距离+minNode距离
distanceMap[toNode] = min(distanceMap[toNode],
edge->weight + distance);
}
//此时选择的最小节点已经处理完毕了,可以放在touchSet里
touchSet.insert(minNode);
//继续更新获取下一个最小节点,当所有节点都touch了返回空节点
minNode = getMinDistanceAndUnuseSelecedNode(distanceMap, touchSet);
}
return distanceMap;
}
unordered_map<Node*, int> Graph::dijkstral(Node* head, int heapSize){
MyHeap *nodeHeap = new MyHeap(heapSize);
unordered_map<Node*, int> result;
nodeHeap->updateOrIngore(head, 0);
while(!nodeHeap->isEmpty()){
NodeRecord* record = nodeHeap->pop();
Node* cur = record->node;
int distance = record->distance;
for(Edge* edge : cur->nextEdges){
nodeHeap->updateOrIngore(edge->to,
distance + edge->weight);
}
result[cur] = distance;
}
return result;
}
list<Node*> sortedTopology(Graph* graph) {
unordered_map<Node*, int> inMap;
queue<Node*> zeroInQueue;
for (auto &it : graph->nodes) {
auto node = it.second;
inMap[node] = node->in;
if (node->in == 0) {
zeroInQueue.push(node);
}
}
list<Node*> result;
while (!zeroInQueue.empty()) {
Node* cur = zeroInQueue.front();
zeroInQueue.pop();
result.push_back(cur);
for (Node* next : cur->nexts) {
inMap[next] = inMap[next] - 1;
if (inMap[next] == 0) {
zeroInQueue.push(next);
}
}
}
return result;
}
#endif //C__TEST02_GRAPH_HPP
主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律