一. 常见算法模板
1. 基础代码,具体释义后序有空补充
头文件
#ifndef __GRAPH__H__
#define __GRAPH__H__
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct Edge;
struct Node {
int _val;
int _in;
int _out;
std::vector<Node *> _next;
std::vector<Edge *> _edges;
Node(int val) : _val(val) {
_in = 0;
_out = 0;
}
};
struct Edge {
public:
int _weight;
Node _from;
Node _to;
public:
Edge(int weight, Node from, Node to)
: _weight(weight), _from(from), _to(to) {}
};
class MySets {
public:
std::unordered_map<Node *, std::list<Node *>> _setMap;
MySets(std::list<Node *> nodes) {
for (auto node : nodes) {
std::list<Node *> myset;
myset.push_back(node);
_setMap.insert(make_pair(node, myset));
}
}
bool isSameSet(Node *from, Node *to);
void unionSet(Node *from, Node *to);
};
class Graph {
public:
std::map<int, Node *> _nodes;
std::set<Edge *> _edges;
std::list<Node *> _unionNodes;
public:
Graph() {}
~Graph() {}
void bfs(Node *node);
void dfs(Node *node);
void showMap();
std::list<Node *> sortedToPology(Graph *graph);
std::set<Edge *> kruskalMST(Graph *graph);
std::set<Edge *> primMST(Graph *graph);
std::unordered_map<Node *, int> dijkstral(Node *head);
private:
Node *
getMinDistanceAndUnselectNode(std::unordered_map<Node *, int> distanceMap,
std::set<Node *> selectNodes);
};
#endif
源文件
#include "Graph.h"
#include
#include
Graph *createGraph(int (*arr)[3], int rawSize, int colSize) {
if (arr == nullptr) {
return nullptr;
}
Graph *graph = new Graph;
for (int i = 0; i < rawSize; ++i) {
int weight = arr[i][0];
int from = arr[i][1];
int to = arr[i][2];
if (!(graph->_nodes.find(from) != graph->_nodes.end())) {
graph->_nodes.insert(std::make_pair(from, new Node(from)));
}
if (!(graph->_nodes.find(to) != graph->_nodes.end())) {
graph->_nodes.insert(std::make_pair(to, new Node(to)));
}
auto iter = graph->_nodes.find(from);
Node *fromNode = iter->second;
iter = graph->_nodes.find(to);
Node *toNode = iter->second;
Edge newEdg(weight, *fromNode, *toNode);
fromNode->_next.push_back(toNode);
fromNode->_out++;
toNode->_in++;
fromNode->_edges.push_back(&newEdg);
graph->_edges.insert(&newEdg);
}
return graph;
}
void Graph::dfs(Node *node) {
if (node == nullptr) {
return;
}
std::stack<Node *> myStack;
std::set<Node *> mySet;
myStack.push(node);
mySet.insert(node);
std::cout << "cur val = " << node->_val << std::endl;
while (!myStack.empty()) {
Node *curNode = myStack.top();
myStack.pop();
for (auto iter : curNode->_next) {
auto it = mySet.find(iter);
if (it == mySet.end()) {
myStack.push(curNode);
myStack.push(iter);
mySet.insert(iter);
std::cout << "cur val = " << iter->_val << std::endl;
break;
}
}
}
}
void Graph::showMap() {
for (auto iter : _nodes) {
std::cout << "val = " << iter.first << " Node.val = " << iter.second->_val
<< std::endl;
}
}
void Graph::bfs(Node *node) {
if (node == nullptr) {
return;
}
std::queue<Node *> myQueue;
std::set<Node *> mySet;
myQueue.push(node);
mySet.insert(node);
while (!myQueue.empty()) {
Node *curNode = myQueue.front();
myQueue.pop();
std::cout << "cur val = " << curNode->_val << std::endl;
for (auto cur : curNode->_next) {
auto it = mySet.find(cur);
if (it == mySet.end()) {
myQueue.push(cur);
mySet.insert(cur);
}
}
}
}
void test() {
int arr[8][3] = {{7, 1, 8}, {1, 1, 2}, {3, 1, 4}, {1, 8, 7},
{5, 2, 7}, {4, 2, 6}, {2, 4, 6}, {1, 7, 6}};
Graph *graph = createGraph(arr, 8, 3);
graph->showMap();
auto iter = graph->_nodes.find(1);
Node *node1 = iter->second;
graph->dfs(node1);
}
bool MySets::isSameSet(Node *from, Node *to) {
auto iter = _setMap.find(from);
std::list<Node *> fromSet = iter->second;
iter = _setMap.find(to);
std::list<Node *> toSet = iter->second;
return fromSet == toSet;
}
void MySets::unionSet(Node *from, Node *to) {
auto iter = _setMap.find(from);
std::list<Node *> fromSet = iter->second;
iter = _setMap.find(to);
std::list<Node *> toSet = iter->second;
for (auto node : toSet) {
fromSet.push_back(to);
_setMap.insert(std::make_pair(node, fromSet));
}
}
std::set<Edge *> Graph::kruskalMST(Graph *graph) {
std::set<Edge *> result;
if (graph == nullptr) {
return result;
}
MySets myset(graph->_unionNodes);
std::priority_queue<Edge *> myPriortQueue;
for (auto edge : graph->_edges) {
myPriortQueue.push(edge);
}
while (!myPriortQueue.empty()) {
Edge *edge = myPriortQueue.top();
myPriortQueue.pop();
if (!myset.isSameSet(&edge->_from, &edge->_to)) {
result.insert(edge);
myset.unionSet(&edge->_from, &edge->_to);
}
}
return result;
}
std::set<Edge *> Graph::primMST(Graph *graph) {
std::set<Edge *> myresult;
std::priority_queue<Edge *> mypriorityQueue;
std::unordered_set<Node *> myset;
for (auto node : graph->_nodes) {
if (myset.find(node.second) != myset.end()) {
myset.insert(node.second);
for (auto edge : node.second->_edges) {
mypriorityQueue.push(edge);
}
while (!mypriorityQueue.empty()) {
auto edge1 = mypriorityQueue.top();
mypriorityQueue.pop();
auto node1 = &edge1->_to;
if (myset.find(node1) != myset.end()) {
myset.insert(node1);
myresult.insert(edge1);
for (auto nextEdge : node1->_edges) {
mypriorityQueue.push(nextEdge);
}
}
}
}
}
return myresult;
}
Node *Graph::getMinDistanceAndUnselectNode(
std::unordered_map<Node *, int> distanceMap, std::set<Node *> selectNodes) {
Node *result = nullptr;
int minDistance = INT_MAX;
for (auto entry : distanceMap) {
int distance = entry.second;
Node *node1 = entry.first;
if ((selectNodes.find(node1) != selectNodes.end()) &&
distance < minDistance) {
result = node1;
minDistance = distance;
}
}
return result;
}
std::unordered_map<Node *, int> Graph::dijkstral(Node *head) {
std::unordered_map<Node *, int> distanceMap;
if (head == nullptr) {
return distanceMap;
}
distanceMap.insert(std::make_pair(head, 0));
std::set<Node *> selectNodes;
Node *minhead = getMinDistanceAndUnselectNode(distanceMap, selectNodes);
while (minhead != nullptr) {
int distance = distanceMap.find(minhead)->second;
for (auto edges : minhead->_edges) {
Node *toNode = &edges->_to;
if (distanceMap.find(toNode) != distanceMap.end()) {
distanceMap.insert(std::make_pair(toNode, distance + edges->_weight));
}
distanceMap.insert(
std::make_pair(&edges->_to, std::min(distanceMap.find(toNode)->second,
distance + edges->_weight)));
}
selectNodes.insert(minhead);
minhead = getMinDistanceAndUnselectNode(distanceMap, selectNodes);
}
return distanceMap;
}
std::list<Node *> Graph::sortedToPology(Graph *graph) {
std::list<Node *> result;
if (graph == nullptr) {
return result;
}
std::unordered_map<Node *, int> inMap;
std::queue<Node *> zeroInQueue;
for (auto node : graph->_nodes) {
inMap.insert(std::make_pair(node.second, node.second->_in));
if (node.second->_in == 0) {
zeroInQueue.push(node.second);
}
}
while (!zeroInQueue.empty()) {
auto node = zeroInQueue.front();
zeroInQueue.pop();
result.push_back(node);
for (auto next : node->_next) {
inMap.insert(std::make_pair(next, inMap.find(next)->second - 1));
if (inMap.find(next)->second == 0) {
zeroInQueue.push(next);
}
}
}
return result;
}
int main(int argc, const char **argv) {
test();
return 0;
}