定义
图是由一组顶点和一组能够将两个顶点的边组成的,如果点对是有序的,那么图就叫有向图。
怎么样在程序中表示一个图?
1.邻接矩阵
使用邻接矩阵的好处:
1.直观、简单
2.方便检查任意一对顶点间是否存在边
3.方便找任一顶点的所有邻接点
4.方便计算任一顶点的度(出度和入度)
缺点:
1.浪费空间,如果图是稀疏的,有大量无效元素.
2.浪费时间,统计稀疏图一共有多少条边.
2.邻接表
图的概念
C/C++实现
class Graph
{
private:
class Edge
{
private:
int to;
int weight;
public:
Edge(int t, int w) : to(t), weight(w) {
}
int Weight() {
return weight; }
int To()
{
return to;
}
};
int Vertices;//顶点数
std::unique_ptr<std::list<Edge>[]>v;//邻接表
std::unique_ptr<int[]>Indegree;//记录顶点的入度
std::unique_ptr<int[]>outdegree;//记录顶点的出度
public:
Graph(int n = 10) :Vertices(n), v(new std::list<Edge>[n]), Indegree(new int[n]{
0}), outdegree(new int[n]{
0}){
}
addEdge(int from, int to, int weight = 0)
{
if (from >= Vertices || from < 0 || to >= Vertices || to < 0 || from == to)
{
std::cout << "顶点编号输入错误,无法添加" <<std::endl;
return;
}
Edge e(to, weight);
v[from].push_back(e);
Indegree[to]++;
outdegree[from]++;
}
void showweight(int from, int to)
{
if (!outdegree[from])
{
std::cout << "没有从" << from << "到" << to << "路径" << std::endl;
return;
}
if (!Indegree[to])
{
std::cout << "没有从" << from << "到" << to << "路径" << std::endl;
return;
}
for (auto a = v[from].begin(); a != v[from].end(); a++)
{
if ((*a).To() == to)
{
std::cout << from << "--" << to << "的权重是:";
std::cout << (*a).Weight() << std::endl;
return;
}
}
std::cout << "没有从" << from << "到" << to << "路径" << std::endl;
return;
}
bool Topsort() //拓扑排序
{
std::queue<int>q;//入度为0的点进队
for (int i = 0; i < Vertices; ++i)
if (Indegree[i] == 0) //入度为0的
q.push(i);
int Count = 0;
while (!q.empty())
{
int x = q.front();
q.pop();
std::cout << x << " ";//输出顶点;
for (auto a = v[x].begin(); a != v[x].end(); a++) //v的每个邻接点
{
if (--Indegree[(*a).To()] == 0)
{
q.push((*a).To());
}
}
Count++;
}
if (Count < Vertices)
{
std::cout << "存在回路!" << std::endl;
return false;
}
else
return true;
}
bool DFS(int from, int to)//深度优先
{
std::unique_ptr<bool[]>visited(new bool[Vertices] {
false});
std::stack<int>s;
s.push(from);
while (!s.empty())
{
int temp = s.top();
s.pop