CH8 图 (C++类模板)

MyGraph.h

#ifndef MYGRAPH_H
#define MYGRAPH_H

#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <iomanip>
#include <math.h>
using namespace std;

template <class T>
struct Edge
{
	T adjvex;
	double lowcost;
};

struct EdgeNode
{
	int adjvex;
	EdgeNode* nextedge;
	double weight;
};

template <class T>
struct VexNode
{
	T data;
	EdgeNode* firstedge;
};

template <class T>
class MGraph
{
private:
	int vexnum, edgenum;
	vector< vector<double> > edges;
	vector< VexNode<T> > adjlist;
	vector<T> vexs;
	void DFS(int v, vector<bool>& vis);
public:
	MGraph(T v[], int n, int e);
	T GetVexValue(int i);
	double GetEdgeValue(int i, int j);
	int MiniNum(Edge<T> miniedges[]);
	void Print();
	void DFSTraverse();
	void BFSTraverse();
	void Prim(int v);
	void Dijkstra(int v, int path[], double dist[]);
};

template <class T>
void MGraph<T>::Prim(int v)
{
	Edge<T>* miniedges = new Edge <T>[vexnum];
	for (int i = 0; i < vexnum; i++)
	{
		miniedges[i].adjvex = GetVexValue(v);
		miniedges[i].lowcost = GetEdgeValue(v, i);
	}
	miniedges[v].lowcost = 0;
	for (int i = 0; i < vexnum - 1; i++)
	{
		int k = MiniNum(miniedges);//函数定义
		cout << miniedges[k].adjvex << "-->" << GetVexValue(k) << endl;
		miniedges[k].lowcost = 0;
		for (int j = 0; j < vexnum; j++)
		{
			if (GetEdgeValue(k, j) < miniedges[j].lowcost)
			{
				miniedges[j].adjvex = GetVexValue(k);
				miniedges[j].lowcost = GetEdgeValue(k, j);
			}
		}
	}
	delete[]miniedges;
}

template <class T>
MGraph<T>::MGraph(T v[], int n, int e)
{
	vexnum = n;
	edgenum = e;
	vexs.resize(vexnum);
	edges.resize(vexnum);
	for (int i = 0; i < n; i++)
		vexs[i] = v[i];
	for (int i = 0; i < n; i++)
		edges[i].resize(vexnum);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (i == j)
				edges[i][j] = 0;
			else
				edges[i][j] = INFINITY;
		}
	}
	int va, vb;
	double w;
	EdgeNode* p;
	adjlist.resize(vexnum);
	for (int i = 0; i < vexnum; i++)
	{
		adjlist[i].data = v[i];
		adjlist[i].firstedge = NULL;
	}
	for (int i = 0; i < e; i++)
	{
		cout << "输入第" << i + 1 << "条边的起点、终点、权值: ";
		cin >> va >> vb >> w;
		edges[va][vb] = edges[vb][va] = w;
		p = new EdgeNode;
		p->adjvex = vb;
		p->weight = w;
		p->nextedge = adjlist[va].firstedge;
		adjlist[va].firstedge = p;
		p = new EdgeNode;
		p->adjvex = va;
		p->weight = w;
		p->nextedge = adjlist[vb].firstedge;
		adjlist[vb].firstedge = p;
	}
	cout << "该图的邻接表为:" << endl;
	for (int i = 0; i < vexnum; i++)
	{
		cout << adjlist[i].data << "->";
		for (EdgeNode* p = adjlist[i].firstedge; p; p = p->nextedge)
		{
			cout << p->adjvex << "->";
		}
		cout << '\n';
	}
}

template <class T>
T MGraph<T>::GetVexValue(int i)
{
	return vexs[i];
}

template <class T>
double MGraph<T>::GetEdgeValue(int i, int j)
{
	return edges[i][j];
}

template <class T>
int MGraph<T>::MiniNum(Edge<T> miniedges[])
{
	double min = INFINITY;
	int k = -1;
	for (int i = 0; i < vexnum; i++)
		if (miniedges[i].lowcost != 0 && miniedges[i].lowcost < min)
		{
			min = miniedges[i].lowcost;
			k = i;
		}
	return k;
}

template <class T>
void MGraph<T>::Print()
{
	for (int i = 0; i < vexnum; i++)
	{
		for (int j = 0; j < vexnum; j++)
		{
			if (edges[i][j] == INFINITY)
				cout << "INFINITY" << " ";
			else
				cout << setw(8) << edges[i][j] << " ";
		}
		cout << endl;
	}
}

template <class T>
void MGraph<T>::DFSTraverse()
{
	vector<bool> visited;
	visited.resize(vexnum);
	for (int i = 0; i < vexnum; i++)
		visited[i] = false;
	for (int i = 0; i < vexnum; i++)
	{
		if (!visited[i])
			DFS(i, visited);
	}
}

template <class T>
void MGraph<T>::DFS(int v, vector<bool>& visited)
{
	cout << vexs[v] << " ";
	visited[v] = true;
	for (int i = 0; i < vexnum; i++)
	{
		if (edges[i][v] < 1000 && !visited[i])
		{
			DFS(i, visited);
		}
	}
}

template <class T>
void MGraph<T>::BFSTraverse()
{
	queue<int> q;
	vector<bool> visited;
	visited.resize(vexnum);
	for (int i = 0; i < vexnum; i++)
	{
		visited[i] = false;
	}
	for (int i = 0; i < vexnum; i++)
	{
		if (!visited[i])
		{
			cout << i << " ";
			visited[i] = true;
			q.push(i);
			while (!q.empty())
			{
				int now = q.front();
				q.pop();
				for (int j = 0; j < vexnum; j++)
				{
					if (edges[now][j] < 10000 && !visited[j])
					{
						cout << j << " ";
						visited[j] = true;
						q.push(j);
					}
				}
			}
		}
	}
}

template <class T>
void MGraph<T>::Dijkstra(int v, int path[], double dist[])
{
	vector<bool> visited;
	visited.resize(vexnum);
	for (int i = 0; i < vexnum; i++)
	{
		visited[i] = false;
		dist[i] = edges[v][i];
		if (dist[i] < INFINITY)
		{
			path[i] = v;
		}
		else
		{
			path[i] = -1;
		}
	}
	dist[v] = 0;
	visited[v] = true;
	for (int i = 0; i < vexnum; i++)
	{
		double minn = INFINITY;
		int k = 0;
		for (int j = 0; j < vexnum; j++)
		{
			if (!visited[j] && dist[j] < minn)
			{
				k = j;
				minn = dist[j];
			}
		}
		visited[k] = true;
		for (int w = 0; w < vexnum; w++)
		{
			if (!visited[w] && dist[w] > dist[k] + edges[k][w])
			{
				dist[w] = dist[k] + edges[k][w];
				path[w] = k;
			}
		}
	}
}
#endif // MYGRAPH_H

main.cpp

#include "MyGraph.h"
using namespace std;

int main()
{
	int n, m, v;
	int ed[100], path[100];
	double dist[100];
	cout << "输入顶点个数: ";
	cin >> n;
	cout << "输入边的条数: ";
	cin >> m;
	for (int i = 0; i < n; i++)
	{
		ed[i] = i;
	}
	MGraph <int> mgraph(ed, n, m);
	cout << "该图的邻接矩阵为: " << endl;
	mgraph.Print();
	cout << "DFS遍历: ";
	mgraph.DFSTraverse();
	cout << endl;
	cout << "BFS遍历: ";
	mgraph.BFSTraverse();
	cout << endl << endl;;
	while (1)
	{
		cout << "生成最小生成树" << endl;
		cout << "输入源点: ";
		cin >> v;
		mgraph.Prim(v);
		cout << endl;
		cout << "最短路径" << endl;
		cout << "输入源点: ";
		int vv;
		cin >> vv;
		mgraph.Dijkstra(vv, path, dist);
		path[vv] = -1;
		for (int i = 0; i < n; i++)
		{
			cout << "第" << i << "个顶点到源点的最短距离为:" << dist[i] << "   从源点到该点路径为:";
			vector<int> temp;
			int loc = i;
			while (loc != -1)
			{
				temp.push_back(loc);
				loc = path[loc];
			}
			for (int j = temp.size() - 1; j >= 0; j--)
			{
				cout << temp[j] << " ";
			}
			cout << endl;
		}
	}
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈笑死哈哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值