图的数据结构
1.简介
图包括很多种类型,该文章仅介绍无向图与有向图
首先,我们必须有一个Bag数组来装下图
2.Bag的实现
由于仅展示
#include<vector>
class Bag
{
private:
class Node
{
public:
int val;
Node* next;
Node(int v, Node* x) :
val(v), next(x) {}
};
Node* head;
public:
Bag():head(nullptr){}
~Bag()
{
while (head)
{
Node*temp = head;
head = head->next;
delete temp;
}
}
void put(int val)
{
Node*temp = new Node(val, head);
head = temp;
}
std::vector<int> Travel()
{
Node*temp = head;
std::vector<int>result;
while (temp)
{
result.push_back(temp->val);
temp = temp->next;
}
return result;
}
};
最简单的链表形式,不提供删除等操作
3.无向图
3.1 Graph类
无向图,顾名思义,没有方向,一条路径是双向的
class Graph
{
protected: //成员设为保护成员方便继承使用
int V;//顶点个数
int E;//边的数目
Bag *adj;
public:
Graph(int v);
virtual ~Graph();
int GetV() { return V; }
int GetE() { return E; }
virtual void AddEdge(int w, int v);
std::vector<int> GetBagValve(int w);
};
3.2 其他方法的实现
Graph::Graph(int v)
{
V = v;
adj = new Bag[V]();
}
void Graph::AddEdge(int w, int v)
{
adj[w].put(v);
adj[v].put(w);
++E;
}
Graph::~Graph()
{
delete[] adj;
}
std::vector<int> Graph::GetBagValve(int w)
{
return adj[w].Travel();
因为比较简单,此处不进行解释
4.有向图
4.1 DirectGraph类的实现
class DirectGraph :public Graph
{
public:
DirectGraph(int v) :
Graph(v) {}
void AddEdge(int w, int v) override;
DirectGraph reverse();
};
DirGraph类直接继承于Graph类,有效防止了重复代码的书写
4.2 方法的实现
void DirectGraph::AddEdge(int w, int v)
{
adj[w].put(v);
++E;
}
DirectGraph DirectGraph::reverse() //提供了反转方法,这在后续的拓扑排序中有用
{
DirectGraph R(V);
for (int v = 0; v < V; v++)
{
std::vector<int>temp = GetBagValve(v);
for (int i = 0; i < temp.size(); ++i)
R.AddEdge(temp[i], v);
}
return R;
}
5. BFS与DFS类的base类实现
5.1类的实现
class base
{
protected:
bool*marked; // 标记数组
int*EdgeTo; //从哪条边访问的?
int s; //起点
public:
base() = default;
base(int s, Graph &G);
virtual ~base() //析构函数
{
delete[] marked;
delete[] EdgeTo;
}
bool HasPathTo(int v); 是否有起点s到v的路径?
std::stack<int>PathTo(int v); 取路径
};
5.2 类方法的实现
bool base::HasPathTo(int v)
{
return marked[v];
}
std::stack<int> base::PathTo(int v)
{
if (HasPathTo(v))
return std::stack<int>();
std::stack<int>temp;
while (v != s)
{
temp.push(v);
v = EdgeTo[v];
}
temp.push(s);
return temp;
}
base::base(int s, Graph & G) //构造函数
{
marked = new bool[G.GetV()]{ 0 };
EdgeTo = new int[G.GetV()];
this->s = s;
}
void BFS::bfs(Graph&G,int s)
{
std::queue<int>q;
q.push(s);
cout << s << endl;
marked[s] = true;
while (!q.empty())
{
s = q.front();
q.pop();
std::vector<int>temp = G.GetBagValve(s);
for (auto it = temp.begin(); it != temp.end(); ++it)
if (!marked[*it])
{
cout << *it << endl;
EdgeTo[*it] = s;
marked[*it] = true;
q.push(*it);
}
}
}
6.深度优先搜索DFS类的实现
6.1 class的实现
class DFS:public base
{
public:
DFS(int s, Graph &G) //构造函数,开始搜索
:base(s, G) {dfs(G, s);}
void dfs(Graph&G, int w);
};
6.2 类方法的实现
void DFS::dfs(Graph & G, int w)
{
cout << w << endl;
marked[w] = true;
std::vector<int> temp = G.GetBagValve(w);
for (int i = 0; i < temp.size(); ++i)
if (!marked[temp[i]])
{
EdgeTo[temp[i]] = w;
dfs(G, temp[i]);
}
}
7 广度优先搜索bfs类的实现
7.1 类的实现
class BFS:public base
{
public:
BFS(int x,Graph&G):
base(x, G) {bfs(G, x);}
void bfs(Graph&G,int x);
};
与BFS类大同小异
7.2 bfs方法的实现
void BFS::bfs(Graph&G,int s)
{
std::queue<int>q;
q.push(s);
cout << s << endl;
marked[s] = true;
while (!q.empty())
{
s = q.front();
q.pop();
std::vector<int>temp = G.GetBagValve(s);
for (auto it = temp.begin(); it != temp.end(); ++it)
if (!marked[*it])
{
cout << *it << endl;
EdgeTo[*it] = s;
marked[*it] = true;
q.push(*it);
}
}
}
有没有很熟悉,没错,二叉树的层序遍历便是dfs