数据结构与算法学习(7)
一.图
1.图的定义
class Node;
class Edge {
public:
int weight;
Node* from;
Node* to;
Edge(int weight,Node* from,Node* to):weight(weight),from(from),to(to){}
};
class Node {
public:
int val;
int out;
int in;
vector<Node*>* nexts;
vector<Edge*>* edges;
Node(int val):val(val),out(0),in(0){
nexts = new vector<Node*>();
edges = new vector<Edge*>();
}
};
class Graph {
public:
unordered_map<int, Node*>* nodes;
unordered_set<Edge*>* edges;
Graph() {
nodes = new unordered_map<int, Node*>();
edges = new unordered_set<Edge*>();
}
};
2.深度优先遍历
void dfs(Node* node) {
if (node == nullptr)
return;
stack<Node*> stk;
unordered_set<Node*> s;
stk.push(node);
s.insert(node);
cout << node->val << endl;
while (!stk.empty())
{
Node* topNode = stk.top();
stk.pop();
for (auto tmp : *topNode->nexts) {
if (s.count(tmp) <= 0) {
stk.push(topNode);
stk.push(tmp);
s.insert(tmp);
cout << tmp->val << endl;
break;
}
}
}
}
3.广度优先遍历
void bfs(Node* node) {
if (node == nullptr)
return;
queue<Node*> q;
unordered_set<Node*> s;
q.push(node);
s.insert(node);
while (!q.empty())
{
Node * frontNode = q.front();
q.pop();
cout << node->val << endl;
for (auto tmp : *frontNode->nexts) {
if (s.count(tmp) <= 0) {
s.insert(tmp);
q.push(tmp);
}
}
}
}
4.拓扑排序
vector<Node*> TuoPuPaiXu(Graph& g) {
unordered_map<Node*, int> hasTablel;
queue<Node*> q;
for (auto t : *g.nodes) {
Node* node = t.second;
hasTablel[node] = node->in;
if (node->in == 0)
q.push(node);
}
vector<Node*> arr;
while (!q.empty())
{
Node* node = q.front();
q.pop();
arr.emplace_back(node);
for (auto next : *node->nexts) {
hasTablel[next] = hasTablel[next] - 1;
if (hasTablel[next] == 0)
q.push(next);
}
}
return arr;
}
5.K算法求最小生成树
class MySets {
private:
unordered_map<Node*, vector<Node*>*> setMap;
public:
MySets(vector<Node*>& arr) {
for (auto node : arr) {
vector<Node*>* tmp = new vector<Node*>();
tmp->emplace_back(node);
setMap[node] = tmp;
}
}
bool IsSameSet(Node* from, Node* to) {
auto fromVector = setMap[from];
auto toVector = setMap[to];
return fromVector == toVector;
}
void Union(Node* from, Node* to) {
auto fromVector = setMap[from];
auto toVector = setMap[to];
for (auto toNode : *toVector) {
fromVector->emplace_back(toNode);
setMap[toNode] = fromVector;
}
}
};
struct cmp
{
bool comparator(const Edge* a, const Edge* b)
{
return a->weight > b->weight;
}
};
unordered_set<Edge*> K(Graph& g) {
vector<Node*> arr;
for (auto pair : *g.nodes)
arr.emplace_back(pair.second);
MySets mySets(arr);
priority_queue<Edge*, cmp> q;
for (auto edge : *g.edges)
q.push(edge);
unordered_set<Edge*> res;
while (!q.empty())
{
Edge* edge = q.top();
q.pop();
if (!mySets.IsSameSet(edge->from, edge->to)) {
res.insert(edge);
mySets.Union(edge->from, edge->to);
}
}
return res;
}
6.P算法求最小生成树
unordered_set<Edge*> P(Graph& g) {
unordered_set<Node*> hasTable;
unordered_set<Edge*> res;
priority_queue<Edge*, cmp> q;
for (auto pair : *g.nodes) {
Node* node = pair.second;
if (hasTable.count(node) <= 0) {
hasTable.insert(node);
for (auto edge : *node->edges)
q.push(edge);
while (!q.empty())
{
Edge* edge = q.top();
q.pop();
Node* newNode = edge->to;
if (hasTable.count(newNode) <= 0) {
hasTable.insert(newNode);
res.insert(edge);
for (auto newEdges : *newNode->edges)
q.push(newEdges);
}
}
}
}
return res;
}
7.Dijkstra算法
unordered_map<Node*, int> Dijkstra(Node* head) {
unordered_map<Node*, int> distanceMap;
unordered_set<Node*> selectedNodes;
distanceMap[head] = 0;
Node* minNode = GetMinDistance(distanceMap, selectedNodes);
while (minNode)
{
int distance = distanceMap[minNode];
for (auto edge : *minNode->edges) {
Node* toNode = edge->to;
if (!distanceMap.count(toNode)) {
distanceMap[toNode] = distance + edge->weight;
}
distanceMap[toNode] = min(distanceMap[toNode],distance + edge->weight);
}
selectedNodes.insert(minNode);
minNode = GetMinDistance(distanceMap, selectedNodes);
}
return distanceMap;
}
Node* GetMinDistance(unordered_map<Node*, int>& distanceMap, unordered_set<Node*>& selectedNodes) {
int minDistance = INT_MAX;
Node* minNode = nullptr;
for (auto pair : distanceMap) {
Node* node = pair.first;
int distance = pair.second;
if (!selectedNodes.count(node) && distance < minDistance) {
minDistance = distance;
minNode = node;
}
}
return minNode;
}