二、最小生成树算法之Prim算法
数据结构中的Prim算法是先将一个顶点加入集合,寻找与其最近的顶点加入集合,然后依次寻找与这两个顶点中最近的顶点加入集合,以此类推直到所有顶点都被访问到。
由于迷宫中所有边的权都相同,且生成迷宫需要随机性,所以寻找最近顶点这一步就变为:
随机选取集合中某一顶点,检索其相邻顶点是否被访问过,如果全部被访问过,将这个顶点移除集合,如果尚存在未被访问过的顶点,就随机选择其中一个并连接它们。
最终形成的迷宫如图
由于准备阶段在上一篇文章中已阐述过,本篇只列出算法函数
void Prim()
{
int x = 0, y = 0;
vector<Map*>rode;//使用向量容器作为集合
rode.push_back(start);//start作为根
map[x][y]->val = 1;//标记访问过的顶点
while (!rode.empty())
{
Sleep(0);
int select = rand() % rode.size();//从集合中随机选取一个顶点
x = rode[select]->x;
y = rode[select]->y;
int v = visit(x, y);
if (v == 0)
{
rode.erase(rode.begin()+select);//如果该顶点的相邻顶点全部被访问过,移除它
}
else
{//以下代码为从可访问的顶点中随机选取一个
vector<int>put;
if (v % 10 == 1)
put.push_back(UP);
if (v % 100 >= 10)
put.push_back(DOWN);
if (v % 1000 >= 100)
put.push_back(LEFT);
if (v >= 1000)
put.push_back(RIGHT);
int choose = rand() % put.size();
//以下代码把要移除的墙涂白
if (put[choose] == UP)
{
solidrectangle(x*(RODE + WALL) - RODE / 2, y*(RODE + WALL) - RODE / 2 - WALL, x*(RODE + WALL) + RODE / 2, y*(RODE + WALL) - RODE / 2);
y--;
}
else if (put[choose] == DOWN)
{
solidrectangle(x*(RODE + WALL) - RODE / 2, y*(RODE + WALL) + RODE / 2, x*(RODE + WALL) + RODE / 2, y*(RODE + WALL) + RODE / 2 + WALL);
y++;
}
else if (put[choose] == LEFT)
{
solidrectangle(x*(RODE + WALL) - RODE / 2 - WALL, y*(RODE + WALL) - RODE / 2, x*(RODE + WALL) - RODE / 2, y*(RODE + WALL) + RODE / 2);
x--;
}
else if (put[choose] == RIGHT)
{
solidrectangle(x*(RODE + WALL) + RODE / 2, y*(RODE + WALL) - RODE / 2, x*(RODE + WALL) + RODE / 2 + WALL, y*(RODE + WALL) + RODE / 2);
x++;
}
//将它们互相加入对方的相连顶点集合中
rode[select]->push(map[x][y]);
map[x][y]->push(rode[select]);
//把新顶点加入集合
rode.push_back(map[x][y]);
map[x][y]->val = 1;
}
}
}
可以看到最后寻到的路并不曲折