七巧板的四色问题

学习了数据结构图的相关知识后,实验是实现DFS,BFS算法,并且输出七巧板四色问题的所有方案
七巧板这样一个图的邻接矩阵为七巧板的邻接矩阵

首先是类的定义

因为七巧板的图相对比较稀疏,所以用无向图的邻接表存储

struct Edge {
	int adjvex;	//邻接顶点的序号
	Edge* next;	//下一个邻接点
};
enum Color {red, yellow, blue, green, white};
struct Vertex {
	char VertexName;	//顶点名
	Color color = white;	//默认是白色
	Edge* firstedge;	//边结点
};
class Graph {
private:
	Vertex* vertexlist;	//创建对象时动态分配存储顶点的数组
	int vertexNum;	int edgeNum;	//顶点数和边数
	bool* visited;	//记录是否访问过
	int num = 0;	//涂色方案数
public:
	Graph(int n, int e);	//分别是顶点数和边数
	~Graph();
	void initialise();	//初始化
	void DFS(int v);	//深度优先遍历输出各顶点及其颜色
	void BFS();	//广度优先遍历输出各顶点及其颜色
	bool conficting(int v);	//顶点v的颜色与其相邻边是否冲突(没有边视为不冲突)
	void coloring(int v);	//涂色
	void printMatrix();	//输出邻接矩阵
};

然后是类函数的实现。

Graph::Graph(int n, int e) {
	vertexNum = n; edgeNum = e;
	vertexlist = new Vertex[vertexNum];
	visited = new bool[vertexNum];
	for (int i = 0; i < vertexNum; i++) {
		vertexlist[i].VertexName = 'A' + i;	//从A开始依次命名顶点
		vertexlist[i].firstedge = nullptr;
	}
	cout << "依次输入每个边依附顶点的序号" << endl;
	int a, b;
	for (int i = 0; i < 2 * e; i++) {
		cin >> a >> b;
		Edge* s = new Edge;
		s->adjvex = b;
		s->next = vertexlist[a].firstedge;	//插入边结点
		vertexlist[a].firstedge = s;
	}
}
Graph::~Graph() {
	Edge* cur = nullptr;
	for (int i = 0; i < vertexNum; i++) {
		Edge* p = vertexlist[i].firstedge;
		if (p == nullptr)
			continue;	//如果没有边则跳过该顶点
		cur = p->next;
		while (cur != nullptr) {
			delete p;
			p = cur;
			cur = cur->next;
		}
		delete p;
	}
	delete[] visited;
	delete[] vertexlist;
}
void Graph::initialise() {
	num = 0;
	for (int i = 0; i < vertexNum; i++) {
		visited[i] = false;
		vertexlist[i].color = white;
	}
}
void Graph::DFS(int v) {
	if (!visited[v]) {
		cout << vertexlist[v].VertexName << " ";
		switch (vertexlist[v].color) {
			case red: cout << "红色\n";	break;
			case yellow: cout << "黄色\n";	break;
			case blue: cout << "蓝色\n";	break;
			case green: cout << "绿色\n"; break;
			default: cout << "白色\n";	break;
		}
		visited[v] = true;
	}
	Edge* p = vertexlist[v].firstedge;
	int j = 0;
	while (p != nullptr) {
		j = p->adjvex;
		if (!visited[j])
			DFS(j);
		p = p->next;
	}
}
void Graph::BFS() {
	Edge* p;
	int j;
	for (int i = 0; i < vertexNum; i++) {
		if (!visited[i]) {
			cout << vertexlist[i].VertexName << " ";
			switch (vertexlist[i].color) {
				case red: cout << "红色\n";	break;
				case yellow: cout << "黄色\n";	break;
				case blue: cout << "蓝色\n";	break;
				case green: cout << "绿色\n"; break;
				default: cout << "白色\n";	break;
			}
			visited[i] = true;
		}
		p = vertexlist[i].firstedge;
		while (p != nullptr) {
			j = p->adjvex;
			if (!visited[j]) {
				cout << vertexlist[j].VertexName << " ";
				switch (vertexlist[j].color) {
					case red: cout << "红色\n";	break;
					case yellow: cout << "黄色\n";	break;
					case blue: cout << "蓝色\n";	break;
					case green: cout << "绿色\n"; break;
					default: cout << "白色\n";	break;
				}
				visited[j] = true;
			}
			p = p->next;
		}
	}
}
bool Graph::conficting(int v) {
	Edge* p = vertexlist[v].firstedge;
	if (p == nullptr)
		return false;
	else {
		while (p != nullptr) {
			if (vertexlist[v].color == vertexlist[p->adjvex].color)
				return true;
			p = p->next;
		}
		return false;
	}
}
void Graph::coloring(int v) {
	if (v >= vertexNum) {
		cout << "第" << ++num << "种方案:" << endl;
		for (int i = 0; i < vertexNum; i++) {
			cout << vertexlist[i].VertexName << "涂";
			switch (vertexlist[i].color) {
				case red: cout << "红色\n";	break;
				case yellow: cout << "黄色\n";	break;
				case blue: cout << "蓝色\n";	break;
				case green: cout << "绿色\n"; break;
			}
		}
	}
	else {
		//依次尝试4种颜色
		for (int i = 0; i < 4; i++) {
			vertexlist[v].color = (Color)i;
			if (conficting(v))	//颜色冲突,试下一种颜色
				continue;
			else	//颜色不冲突或没有边
				coloring(v+1);
		}
	}
	//所有颜色都冲突时,取消涂色并回溯
	vertexlist[v].color = white;
}
void Graph::printMatrix() {
	//用动态二维数组存储邻接矩阵
	bool** matrix = new bool*[vertexNum];
	for (int i = 0; i < vertexNum; i++)
		matrix[i] = new bool[vertexNum];
	//初始化为0
	for(int i = 0; i < vertexNum; i++)
		for (int j = 0; j < vertexNum; j++) {
			matrix[i][j] = 0;
		}
	//有边的点改为1
	Edge* p;
	for (int i = 0; i < vertexNum; i++) {
		p = vertexlist[i].firstedge;
		while (p != nullptr) {
			matrix[i][p->adjvex] = 1;
			p = p->next;
		}
	}
	//输出
	cout << "邻接矩阵为:" << endl;
	for (int i = 0; i < vertexNum; i++) {
		for (int j = 0; j < vertexNum; j++) {
			cout << matrix[i][j] << "  ";
		}
		cout << endl;
	}
	//释放空间
	for (int i = 0; i < vertexNum; i++)
		delete[] matrix[i];
	delete[] matrix;
}

共有672种涂色方案,输出结果为
输出结果

最后析构时,Visio studio在delete[] vertexlist处会触发一个断点,导致不能正常结束程序
在这里插入图片描述
但试其他图时没有该问题,不知道是什么原因。

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值