七巧板的四色问题
程序员文章站
2022-03-03 11:20:48
...
学习了数据结构图的相关知识后,实验是实现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
处会触发一个断点,导致不能正常结束程序
但试其他图时没有该问题,不知道是什么原因。