不相交集產生隨機迷宮並用深度搜尋列印出路徑

2021-08-20 04:00:05 字數 2808 閱讀 5315

找了網上很多關於迷宮的**,要麼就是只有生成隨機迷宮的,要麼就是已經有了固定迷宮的陣列找路徑,找不到兩者結合在一起的**,沒辦法只能靠自己了。

言歸正傳生成隨機迷宮需要用到查並集思想。

該設計共包含如下三個部分:

1構建隨機迷宮

應用不相交集合構建迷宮的演算法簡要描述如下: 給定乙個nxn 的方格(cells),初始時每個方格的四面都是牆(walls),如圖6-58 (a) 所示,其中的s 是迷宮的開始處,f 是迷宮的結束處。nxn 迷宮的n 個方格0,1,..,n-1初始時每個方格自己成為乙個等價類,即,,.,。生成隨機迷宮的方法是先建立乙個vector動態陣列,將除去上邊框和左邊框的剩下所有可以除去的牆編號(相當於每個單元的下邊牆和右邊牆,例如第乙個單元的下邊牆編號為1,右邊牆為2,以此類推)放入這個陣列中,在陣列中隨機選擇乙個內部牆(連線兩個相鄰方格的牆),如果該內部牆關聯的兩個相鄰的方格屬於不同的等價類就將該牆除去,在除去該牆的同時將這兩個等價類合併。直到所有的方格都在乙個等價類中,就完成了隨機迷宮的生成

2尋找迷宮路徑

搜尋路徑需要用到深度搜尋和非遞迴用法的棧。迷宮一旦建立後,方格作為圖中的頂點,如果兩個相鄰的方格之間沒有牆則兩個頂點之間有邊。為找到從起點到終點的一條唯一的路徑,在該圖上從起點處開始出發進行深度搜尋,如果有邊則進入下一單元將這個單元的bianli屬性標記為false,防止搜尋返回進入死迴圈,並將這個單元的下標壓棧。如果遇到死胡同就將這個下標出棧,回溯。知道找到終點則結束

3列印路徑

深度搜尋完畢則棧中存放了路徑所經過單元的下標,我們用vector陣列將棧中的資料取出,再利用windows.h庫,設定游標屬性並通過簡單的數學計算在控制台輸出相應單元對應的位置,則在地圖中將路徑打出

查並集類

#disjsets.h

#include #include #include#include#include#includeusing namespace std;

class disjsets

bool getbottom(int i)

void get(int n,int m);

void xiansi(int m);

private:

struct cell

};std::vectors;

vectorss;

};#disjsets.cpp

#include "disjsets.h"

disjsets::disjsets(int numelements) :s(numelements)

}//root1和root2為互異的兩個根

void disjsets::unionsets(int root1, int root2)

else if (s[n + m].bianli&&!s[n].bottom)

}else if (n % m!= 0 && s[n - 1].bianli && !s[n - 1].right)

else if ((n+1) % m != 0 && s[n + 1].bianli&&!s[n].right)

else if (n > (m-1) && s[n - m].bianli&&!s[n - m].bottom)

else if (n

else

}}void disjsets::xiansi(int m)

handle hout;

coord pos = ;

hout = getstdhandle(std_output_handle);

console_cursor_info cci; //定義結構體

getconsolecursorinfo(hout, &cci); //獲取游標資訊

cci.dwsize = 1; //設定游標大小

cci.bvisible = 0; //設定游標不可見 false

setconsolecursorinfo(hout, &cci); //設定(應用)游標資訊

setconsoletextattribute(hout, 0x0004 | 0x0008 | 0x8000); //設定字型屬性

for (int y = 0; y < ss.size();y++)

}

#include "disjsets.h"

#include #include #include"stdlib.h"

#include#includeusing namespace std;

int main(int argc, const char * argv)

disjsets s(n*n); //初始化n的平方個單元

//構建迷宮,從wall中隨機選擇一面牆。若牆兩邊的單元沒有連通,則拆掉牆。

while (wall.size()>0)

}else //如果為奇數,則為下方的牆

}wall.erase(wall.begin() + j); //將已經連通的兩個單元之間的牆從wall中移除

} //輸出迷宮

利用不相交集畫迷宮

當我們畫乙個80 50的迷宮時相當於是畫了個80 50的方格仔,把格仔和格仔之間的某些牆拆掉,互相連通的格仔我們稱之為屬於同乙個集合,如果兩個集合不連通,那就稱之為不相交集.畫迷宮的過程就是不斷地拆除格仔與格仔之間的牆,直到第乙個格仔和最後乙個格仔屬於同乙個集合演算法終止.不相交集類.ifndef ...

不相交集ADT

1.不相交集是解決等價關係的一種資料結構,執行合併和查詢的速度都非常快,m次執行合併和查詢的執行時間為 m logn 在乙個集合中,對於每一對元素 a,b a,b s,對於關係r如果滿足下面三個條件,則成關係r為等價關係 1 自反性 對於所有a s,ara 2 對稱性 arb當且僅當bra 3 傳遞...

不相交集ADT

首先我們必須明白不相交集這種資料結構是用來幹什麼的。不相交即主要用來實現動態等價問題的求解。動態 等價問題 這裡不再說明等價關係的概念,這個可以參考數理邏輯之類的書。假設我們有乙個集合和乙個等價關係 針對集合中的任意兩個元素 a 和 b,我們如何確定他們有等價關係 即a b.那麼我們需要等價類的概念...