关于图算法的整理DFS,BFS,Dijkstra,Prim代码

邻接矩阵与邻接表(两者皆可用来表示有向图和无向图)

创建一个基类graph

#pragma once
#include<iostream>
#include<vector>
#include <map>
#include <string>
#include <functional>
#include<algorithm>
#include<queue>
using namespace std;

class graph
{
public:
	graph(bool dir = false)
	{
		directed = dir;
		this->nv = 0;
	}
	graph(vector<string>v, bool dir = false)
	{
		directed = dir;
		nv = v.size();
		vertices = v;
		for (int i = 0; i < nv; i++)
		{
			iov[vertices[i]] = i;
		}
	}
	graph(int n, bool dir = false)
	{
		directed = dir;
		nv = n;
		vertices.resize(nv);
		for (int i = 0; i < nv; i++)
		{
			vertices[i] = to_string(i);
			//vertices.push_back(to_string(i));
			iov[vertices[i]] = i;
		}
	}
	
	virtual void prin() = 0;
	virtual void insertv()
	{
		insertv(to_string(nv));
	}
	virtual bool insertv(string v)
	{
		if (iov.find(v) != iov.end())
		{
			return false;
		}
		vertices.push_back(v);
		iov[v] = nv;
		nv++;
		return true;
	}
	virtual bool insertE(string src, string dst, int weight = 1)
	{
		insertv(src);
		insertv(dst);
		return insertE(iov[src], iov[dst], weight);
	}
	virtual bool insertE(int src, int dst, int weight = 1) = 0;
	virtual bool removeE(string src, string dst)
	{
		if (iov.find(src) == iov.end() || iov.find(dst) == iov.end())
		{
			return false;
		}
		return removeE(iov[src], iov[dst]);
	}
	virtual bool removeE(int src, int dst) = 0;
	virtual void dfs(string v)
	{
		if (iov.find(v) == iov.end())
		{
			return;
		}
		visited.resize(nv);
		for (int i = 0; i < nv; i++)
		{
			visited[i] = false;
		}
		dfs(iov[v]);
	}
protected:
	virtual void dfs(int v) = 0;
	int nv;
	bool directed;
	vector<string>vertices;
	map<string, int>iov;
	vector<bool>visited;
private:
};

 1.首先先看看用邻接矩阵怎么去表示一个图

	//在.h中设置
        //bool dir判断是否为有向图,默认false为无向图,
        vector<vector<int>>adjm;//动态创建邻接矩阵
        mgraph(bool dir = false) :graph(dir)
	{

	}
	mgraph(vector<string>v, bool dir = false) :graph(v, dir)
	{
		setadjm();
	}
	mgraph(int n, bool dir = false) :graph(n, dir)// n为顶点个数
	{
		setadjm();
	}
        

//在.cpp文件中设置
void mgraph:: setadjm()
	{
		adjm.resize(nv);
		for (int i = 0; i < nv; i++)
		{
			adjm[i].resize(nv);
			for (int j = 0; j < nv; j++)
			{
				adjm[i][j] = INT_MAX;
			}
		}
	}

打印生成的邻接矩阵

void mgraph::prin()
	{
		cout << '\t';
		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << '\t';
		}
		cout << endl;
		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << ":\t";
			for (int j = 0; j < nv; j++)
			{
				if (adjm[i][j] == INT_MAX)
				{
					cout << "-\t";
				}
				else cout << adjm[i][j] << '\t';
			}


			cout << endl;
		}cout << endl;
	}

2.生成邻接表

vector<map<int, int>>adjl;//邻接表
lgraph(bool dir = false) :graph(dir){}
	lgraph(vector<string> v, bool dir = false) :graph(v, dir){ setadjl(); }
	lgraph(int n, bool dir = false) :graph(n, dir){ setadjl(); }
void lgraph::setadjl()
	{
		adjl.resize(nv);
		for (auto x : adjl)
		{
			x.clear();
		}
	}

打印生成邻接表

void  lgraph::prin()
	{

		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << "[" << i << "]" << "-->";
			for (auto x : adjl[i])
			{
				cout << vertices[x.first] << "(" << x.second << ")  ";

			}cout << endl;
		}
	}

对邻接矩阵进行插入顶点使用insertV()函数,两点间插入边使用insertE()函数操作,同时对图进行DFS深度优先BFS广度优先遍历,最后学习Dijkstra最短路径算法Prim最小生成树算法

这边就不一一举例了直接上代码

首先是.h文件

#pragma once
#include "graph.h"
class mgraph :public graph
{
protected:
	vector<vector<int>>adjm;
	void setadjm();
	
public:
	mgraph(bool dir = false) :graph(dir)
	{

	}
	mgraph(vector<string>v, bool dir = false) :graph(v, dir)
	{
		setadjm();
	}
	mgraph(int n, bool dir = false) :graph(n, dir)
	{
		setadjm();
	}
	void prin();
	void insertv();
	bool insertv(string v);
	bool insertE(string src, string dst, int weight = 1);
	bool insertE(int src, int dst, int weight = 1);

	bool removeE(string src, string dst);
	bool removeE(int src, int dst);
	void dfs(string v);
	void dfs(int v);

	void bfs(string v);
	void dijkstra(string src);
	void prim(string src);
};

.cpp文件

#include "mgraph.h"


void mgraph:: setadjm()
	{
		adjm.resize(nv);
		for (int i = 0; i < nv; i++)
		{
			adjm[i].resize(nv);
			for (int j = 0; j < nv; j++)
			{
				adjm[i][j] = INT_MAX;
			}
		}
	}

	
void mgraph::prin()
	{
		cout << '\t';
		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << '\t';
		}
		cout << endl;
		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << ":\t";
			for (int j = 0; j < nv; j++)
			{
				if (adjm[i][j] == INT_MAX)
				{
					cout << "-\t";
				}
				else cout << adjm[i][j] << '\t';
			}


			cout << endl;
		}cout << endl;
	}
void mgraph::insertv()
	{
		insertv(to_string(nv));

	}
	bool mgraph::insertv(string v)
	{
		bool r = graph::insertv(v);
		if (!r)
		{
			return false;
		}
		for (int i = 0; i < nv - 1; i++)
		{
			adjm[i].push_back(INT_MAX);
		}
		adjm.push_back(vector<int>(nv, INT_MAX));
		return true;
	}
	bool mgraph::insertE(string src, string dst, int weight )
	{
		return graph::insertE(src, dst, weight);

	}
	bool mgraph::insertE(int src, int dst, int weight )
	{
		if (src < 0 || dst < 0 || src >= nv || dst >= nv)
			return false;
		if (adjm[src][dst] != INT_MAX)
		{
			return false;
		}
		if (!directed)
		{
			adjm[dst][src] = weight;
		}
		adjm[src][dst] = weight;
	}

	bool mgraph::removeE(string src, string dst)
	{
		return graph::removeE(src, dst);

	}
	bool mgraph::removeE(int src, int dst)
	{
		if (src < 0 || dst < 0 || src >= nv || dst >= nv)
			return false;
		if (adjm[src][dst] == INT_MAX)
		{
			return false;
		}
		adjm[src][dst] = INT_MAX;
		if (!directed)
		{
			adjm[dst][dst] = INT_MAX;
		}
		return true;
	}
	void mgraph::dfs(string v)
	{
		graph::dfs(v);
	}
	void mgraph::dfs(int v)
	{
		cout << vertices[v] << " ";
		visited[v] = true;
		for (int i = 0; i < nv; i++)
		{
			if (!visited[i] && adjm[v][i] != INT_MAX)
			{
				dfs(i);
			}

		}
	}

	 void mgraph::bfs(string v)
	{
		if (iov.find(v) == iov.end())
		{
			return;
		}
		visited.resize(nv);
		for (int i = 0; i < nv; i++)
		{
			visited[i] = false;
		}
		queue<int>q;
		cout << v << " ";
		int iv = iov[v];
		visited[iv] = true;
		q.push(iv);
		int w;
		while (!q.empty())
		{
			w = q.front();
			q.pop();
			for (int i = 0; i < nv; i++)
			{
				if (!visited[i] && adjm[w][i] != INT_MAX)
				{
					cout << vertices[i] << " ";
					visited[i] = true;
					q.push(i);
				}
			}
		}
	}
	 void mgraph::dijkstra(string src)
	{
		if (iov.find(src) == iov.end())
		{
			return;
		}
		vector<int>d(nv, INT_MAX);
		vector<int>from(nv, -1);
		vector<bool>known(nv, false);
		d[iov[src]] = 0;
		int mindis, v;
		for (int t = 0; t < nv; t++)
		{
			mindis = INT_MAX;
			v = -1;
			for (int i = 0; i < nv; i++)
			{
				if (known[i] == false && d[i] < mindis){
					mindis = d[i];
					v = i;

				}
			}
			if (v == -1)
			{
				break;
			}
			known[v] = true;
			for (int w = 0; w < nv; w++)
			{
				if (adjm[v][w] != INT_MAX&&!known[w] && d[v] + adjm[v][w] < d[w])
				{
					d[w] = d[v] + adjm[v][w];
					from[w] = v;

				}
			}
		}
		for (int i = 0; i < nv; i++)
		{
			cout << i << '\t';
		}
		cout << endl;
		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << '\t';
		}
		cout << endl;
		for (int i = 0; i < nv; i++)
		{
			cout << d[i] << '\t';
		}
		cout << endl;
		for (int i = 0; i < nv; i++)
		{
			cout << (from[i] >= 0 ? vertices[from[i]] : "-") << '\t';
		}
		cout << endl;
	}
	 void mgraph::prim(string src){
		if (iov.find(src) == iov.end())
		{
			return;
		}
		vector<int>d(nv, INT_MAX);
		vector<int>from(nv, -1);
		vector<bool>known(nv, false);
		d[iov[src]] = 0;
		int mindis, v;
		for (int t = 0; t < nv; t++)
		{
			mindis = INT_MAX;
			v = -1;
			for (int i = 0; i < nv; i++)
			{
				if (known[i] == false && d[i] < mindis){
					mindis = d[i];
					v = i;
				}
			}
			if (v == -1)
			{
				break;
			}
			known[v] = true;
			for (int w = 0; w < nv; w++)
			{
				if (adjm[v][w] != INT_MAX&&!known[w] && adjm[v][w] < d[w])
				{
					d[w] = adjm[v][w];
					from[w] = v;

				}
			}
		}
		for (int i = 0; i < nv; i++)
		{
			cout << i << '\t';
		}
		cout << endl;
		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << '\t';
		}
		cout << endl;
		for (int i = 0; i < nv; i++)
		{
			cout << d[i] << '\t';
		}
		cout << endl;
		for (int i = 0; i < nv; i++)
		{
			cout << (from[i] >= 0 ? vertices[from[i]] : "-") << '\t';
		}
		cout << endl;
	}

同样对邻接表进行一系列操作

邻接表.h文件

#pragma once
#include "graph.h"
class lgraph :public graph
{
protected:
	vector<map<int, int>>adjl;
	void setadjl();
public:
	lgraph(bool dir = false) :graph(dir){}
	lgraph(vector<string> v, bool dir = false) :graph(v, dir){ setadjl(); }
	lgraph(int n, bool dir = false) :graph(n, dir){ setadjl(); }
	void prin();

	void insertv();
	bool insertv(string v);

	 bool insertE(string src, string dst, int weight = 1);
	 bool insertE(int src, int dst, int weight = 1);
	 bool removeE(string src, string dst);
	 bool removeE(int src, int dst);
	void dfs(string v);
	void dfs(int v);


	virtual void bfs(string v);
	void shortest(string src);
};

邻接表.cpp文件

#include "lgraph.h"

	void lgraph::setadjl()
	{
		adjl.resize(nv);
		for (auto x : adjl)
		{
			x.clear();
		}
	}

	
	void  lgraph::prin()
	{

		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << "[" << i << "]" << "-->";
			for (auto x : adjl[i])
			{
				cout << vertices[x.first] << "(" << x.second << ")  ";

			}cout << endl;
		}
	}

	void  lgraph::insertv()
	{
		insertv(to_string(nv));
	}
	bool  lgraph::insertv(string v)
	{
		bool r = graph::insertv(v);
		if (!r)
		{
			return false;
		}
		adjl.push_back(map<int, int>());
		return true;
	}

	 bool  lgraph::insertE(string src, string dst, int weight )
	{
		return graph::insertE(src, dst, weight);

	}
	 bool  lgraph::insertE(int src, int dst, int weight )
	{
		if (src < 0 || dst < 0 || src >= nv || dst >= nv)
			return false;
		if (adjl[src].find(dst) != adjl[src].end())
		{
			return false;
		}
		adjl[src].insert(pair<int, int>(dst, weight));
		if (!directed)
		{
			adjl[dst].insert(pair<int, int>(src, weight));
		}
		return true;

	}
	 bool  lgraph::removeE(string src, string dst)
	{
		return graph::removeE(src, dst);

	}
	bool  lgraph::removeE(int src, int dst)
	{
		if (src < 0 || dst < 0 || src >= nv || dst >= nv)
			return false;
		if (adjl[src].find(dst) == adjl[src].end())
		{
			return false;
		}
		adjl[src].erase(dst);
		if (!directed)
		{
			adjl[dst].erase(src);
		}
		return true;
	}
	void  lgraph::dfs(string v)
	{
		graph::dfs(v);
	}
	void  lgraph::dfs(int v)
	{
		cout << vertices[v] << " ";
		visited[v] = true;
		for (auto x : adjl[v])
		{
			if (!visited[x.first])
			{
				dfs(x.first);
			}
		}
	}


	void  lgraph::bfs(string v)
	{
		if (iov.find(v) == iov.end())
		{
			return;
		}
		visited.resize(nv);
		for (int i = 0; i < nv; i++)
		{
			visited[i] = false;
		}
		queue<int>q;
		cout << v << " ";
		int iv = iov[v];
		visited[iv] = true;
		q.push(iv);
		int w;
		while (!q.empty())
		{
			w = q.front();
			q.pop();
			for (auto x : adjl[w])
			{
				if (!visited[x.first])
				{
					cout << vertices[x.first] << " ";
					visited[x.first] = true;
					q.push(x.first);
				}
			}
		}
	}
	void  lgraph::shortest(string src)
	{
		if (iov.find(src) == iov.end())
		{
			return;
		}
		vector<int>d(nv, INT_MAX);
		vector<int> from(nv, -1);
		d[iov[src]] = 0;
		queue <int>q;
		q.push(iov[src]);
		int v;
		while (!q.empty())
		{
			v = q.front();
			q.pop();
			for (auto w : adjl[v])
			{
				if (d[w.first] == INT_MAX)
				{
					d[w.first] = d[v] + 1;
					from[w.first] = v;
					q.push(w.first);
				}
			}
		}
		for (int i = 0; i < nv; i++)
		{
			cout << vertices[i] << "(" << d[i] << "," << (from[i] >= 0 ? vertices[from[i]] : "-") << ") ";
		}
		cout << endl;
	}

main()函数测试,自行理解后调整

void main()
{
// 	vector<string>v = { "aa", "bb", "cc", "dd" };
// 	lgraph p(true);
// 	string n1, n2;
// 	int m;
// 	cin >> m;
// 	for (int i = 0; i < m; i++)
// 	{
// 		cin >> n1 >> n2;
// 		p.insertE(n1, n2);
// 	}
// 	//p.insertv("x");
// // 	p.insertE("aa", "cc");
// // 	p.insertE(1, 3);
// // 	p.insertE("dd", "ee", 6);
// // 	p.insertE("x", "ee");
// // 	p.insertE("p", "q");
// // 	p.removeE("p", "q");
// 	p.shortest("c");
// 	//p.prin();
// // 	p.dfs("aa");
// // 
// // 	p.bfs("aa");

	mgraph g(true);
	string n1, n2;
	int weight;
	int m;
	cin >> m;
	for (int i = 0; i < m;i++)
	{
		cin >> n1 >> n2 >> weight;
		g.insertE(n1, n2, weight);
	}
	//g.prin();
	//g.dijkstra("a");
	g.prim("a");
	system("pause");
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LV小猪精

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

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

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

打赏作者

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

抵扣说明:

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

余额充值