C語言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)迷宮實(shí)驗(yàn)
本文實(shí)例為大家分享了C語言實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)迷宮實(shí)驗(yàn),供大家參考,具體內(nèi)容如下
分析:迷宮實(shí)驗(yàn)主要有兩部分操作,其一是對(duì)迷宮的生成,其二是尋路使用棧的操作。
步驟:
一、.h文件
1、首先是迷宮的生成,可以使用隨機(jī)數(shù)種子生成,但主要邏輯部分并不在此,所以在這里直接寫死,固定下來。
定義一個(gè)坐標(biāo)類型的結(jié)構(gòu)體,和二維數(shù)組迷宮:
typedef struct {
int x;
int y;
}Pos;
//迷宮類型
typedef struct {
int square[10][10] =
{
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,1},
{1,1,1,1,0,1,1,1,0,1},
{1,0,0,0,0,1,0,1,0,1},
{1,0,1,1,1,1,0,1,1,1},
{1,0,0,0,0,1,0,0,0,1},
{1,0,1,1,0,0,0,1,0,1},
{1,0,1,1,1,0,1,1,1,1},
{1,0,0,0,1,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1},
};
}Maze;
typedef Pos SElemType;
2、然后是對(duì)棧的聲明,棧里儲(chǔ)存的元素為坐標(biāo)類型
//順序棧
#define MAXSIZE 50
typedef struct {
SElemType *base;
SElemType *top; //棧頂指針
int stacksize;
}SqStack;
3、棧操作函數(shù)聲明
typedef int Status; #define OK 1; #define ERROR 0; //棧的相關(guān)操作 //初始化棧 Status initStack(SqStack &s); //壓棧 Status push(SqStack &s, SElemType e); //出棧 SElemType pop(SqStack &s); //清空棧 Status clearStack(SqStack &s); //摧毀棧 void destroyStack(SqStack &s); //遍歷棧 Status stackTravel(SqStack s);
4、迷宮操作函數(shù)聲明
//初始化迷宮(同時(shí)生成起始點(diǎn)和終點(diǎn)) void initMaze(Maze &maze); //打印迷宮 void showMaze(Maze maze); //尋找出路;傳入一個(gè)迷宮和棧找出出路 void findWay(Maze &maze,SqStack &s); //判斷該點(diǎn)的四個(gè)方向是否有通路,有就前進(jìn) Pos isExit(Pos p, Maze maze);
二、.cpp文件
1、導(dǎo)入所需頭文件
#include "pch.h" #include <iostream> #include<time.h> #include<stdlib.h> using namespace std;
2、棧操作實(shí)現(xiàn)
//構(gòu)造空棧
Status initStack(SqStack &s) {
s.base = new SElemType[MAXSIZE];
if (!s.base)
{
exit(OVERFLOW);//分配失敗
}
s.top = s.base;
s.stacksize = MAXSIZE;
return OK;
}
//入棧
Status push(SqStack &s, SElemType e) {
//判斷棧滿
if (s.top-s.base == s.stacksize)
{
return ERROR;
}
//存入元素,*為取指針的值
s.top++;
*s.top = e;
return OK;
}
//出棧,用e返回棧頂值
SElemType pop(SqStack &s) {
SElemType e;
//判斷棧為空
if (s.top == s.base)
{
//若為空則返回一個(gè)(-1,-1)的點(diǎn),判斷由外部調(diào)用時(shí)進(jìn)行
e.x = -1;
e.y = -1;
return e;
}
e = *s.top;
s.top--;
return e;
}
Status clearStack(SqStack &s) {
s.top = s.base;
return OK;
}
void destroyStack(SqStack &s) {
s.top = NULL;
s.stacksize = 0;
free(s.base);
}
Status stackTravel(SqStack s) {
while (s.top != s.base)
{
s.base++;
Pos p = *s.base;
//輸出走過的路徑
cout <<"("<<p.x<<","<<p.y<<")"<< "-->";
if ( p.x == 0 || p.y == 0|| p.x == 9 ||p.y == 9)
{
//終點(diǎn)輸出為“End”
cout << "End";
}
}
cout << endl;
return 0;
}
3、迷宮操作實(shí)現(xiàn)
///////////////////////////////////////迷宮操作////////////////////////////////
//初始化函數(shù),傳入一個(gè)迷宮,隨機(jī)生成起點(diǎn)和終點(diǎn),由于起點(diǎn)有一定限制,所以這里起點(diǎn)也固定為幾個(gè)最合適的點(diǎn)
void initMaze(Maze &maze) {
//生成隨機(jī)數(shù)
srand((unsigned)time(NULL));
int index = rand() % 36 + 1;
int start = index % 6 + 1;
//生成起始點(diǎn)數(shù)值為‘s'
switch (start)
{
case 1:
maze.square[1][1] = 's';
break;
case 2:
maze.square[3][8] = 's';
break;
case 3:
maze.square[3][6] = 's';
break;
case 4:
maze.square[6][8] = 's';
break;
case 5:
maze.square[8][3] = 's';
break;
case 6:
maze.square[8][8] = 's';
break;
}
//隨機(jī)生成終點(diǎn)'e'表示
while (index = rand()%36+1)
{
//出口在頂部
if (index >1 &&index<10 && maze.square[1][index-1]!='s')
{
maze.square[0][index-1] = 'e';
break;
}
//出口在右側(cè)
else if (index>10 &&index <19)
{
if (maze.square[index-10][8] != 1 && maze.square[index-10][8]!='s') {
maze.square[index-10][9] = 'e';
break;
}
}
//底部出口
else if (index >19&&index<28)
{
if (maze.square[8][index - 19] != 's' && maze.square[8][index - 19] != 1) {
maze.square[9][index - 19] = 'e';
break;
}
}
//左側(cè)出口
else if (index >28 && index <=36)
{
if (maze.square[index-28][1] != 1 &&maze.square[index-28][1] != 's')
{
maze.square[index - 28][0] = 'e';
break;
}
}
}
}
void showMaze(Maze maze) {
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (maze.square[i][j] == 1)
{
cout << "* ";
}
else if (maze.square[i][j] == 0)
{
cout << " ";
}
else
{
cout << (char)maze.square[i][j]<<" ";
}
}
cout << endl;
}
}
//尋找迷宮路徑
void findWay(Maze &maze,SqStack &s) {
//首先遍歷找出起始點(diǎn)和終點(diǎn)并保存下來
Pos start,end;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++) {
if (maze.square[i][j] == 's')
{ //起點(diǎn)壓入棧內(nèi)
start.x = i;
start.y = j;
push(s, start);
}
else if (maze.square[i][j] == 'e')
{ //出口
end.x = i;
end.y = j;
}
}
}
//尋找路徑
Pos go = start;
//直到找到出口才結(jié)束
while ( s.top->x != end.x || s.top->y != end.y)
{
//獲得下一步坐標(biāo)
Pos path = isExit(go, maze);
if (path.x != go.x || path.y != go.y)
{
//前進(jìn)
maze.square[path.x][path.y] = 'p';
push(s, path);
go = path;
}
//如果所有放向都走不通(即返回的點(diǎn)是傳入的點(diǎn)),則將其標(biāo)為“@”,出棧到上一個(gè)點(diǎn),繼續(xù)判斷
else
{
//走不通pop
maze.square[path.x][path.y] = '@';
pop(s);
go = *s.top;
}
}
maze.square[end.x][end.y] = 'e';
}
//判斷返回下一步路徑(順序:右下左上),傳入所處位置,從右邊開始判斷是否又通路或者出口,有就返回哪個(gè)方向上的點(diǎn)
Pos isExit(Pos p,Maze maze) {
Pos tempP = p;
if (maze.square[tempP.x][tempP.y+1] == 0 || maze.square[tempP.x][tempP.y + 1] == 'e')
{
tempP.y++;
}
else if(maze.square[tempP.x+1][tempP.y] == 0 || maze.square[tempP.x +1][tempP.y] == 'e')
{
tempP.x++;
}
else if (maze.square[tempP.x][tempP.y - 1] == 0 || maze.square[tempP.x][tempP.y - 1] == 'e')
{
tempP.y--;
}
else if (maze.square[tempP.x - 1][tempP.y] == 0 || maze.square[tempP.x - 1][tempP.y] == 'e')
{
tempP.x--;
}
return tempP;
}
三、main函數(shù)調(diào)用
int main()
{
while (true)
{
//創(chuàng)建一個(gè)迷宮
Maze maze;
initMaze(maze);
//初始化一個(gè)棧
SqStack S;
initStack(S);
cout << "*****************************" << endl;
cout << "* 1、生成迷宮 2、退出 *" << endl;
cout << "*****************************" << endl;
cout << "請(qǐng)輸入你的選擇:";
int select = 0;
cin >> select;
if (select == 1)
{
cout << "生成隨機(jī)起點(diǎn)和出口迷宮:" << endl;
showMaze(maze);
cout << "生成迷宮路徑:" << endl;
findWay(maze, S);
stackTravel(S);
showMaze(maze);
cout << endl;
}
if (select == 2)
{
clearStack(S);
break;
}
}
return 0;
}
四、評(píng)價(jià)
這是個(gè)叫簡(jiǎn)易的迷宮,但基本實(shí)現(xiàn)了迷宮的尋路邏輯,可改進(jìn)的地方有:
1、因?yàn)楹芏嗟胤綄懰懒?,所以?fù)用性不高,可以用循環(huán)遍歷來隨機(jī)生成起點(diǎn),同理迷宮的生成也是這樣
2、判斷路徑可以用遞歸調(diào)用實(shí)現(xiàn)前進(jìn)邏輯
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言中的一維數(shù)組與二維數(shù)組的實(shí)現(xiàn)
數(shù)組可以幫我們巧妙解決生活中的問題,使我們的代碼簡(jiǎn)潔,本文主要介紹了C語言中的一維數(shù)組與二維數(shù)組,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12
C++實(shí)現(xiàn)坦克大戰(zhàn)小游戲EGE圖形界面
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)坦克大戰(zhàn)小游戲EGE圖形界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03
VS2022 CUDA環(huán)境配置的實(shí)現(xiàn)步驟
本文主要介紹了VS2022 CUDA環(huán)境配置的實(shí)現(xiàn)步驟,文中通過圖文示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
關(guān)于c++編譯protobuf時(shí)提示LNK2001 無法解析的外部符號(hào)的問題
這篇文章主要介紹了關(guān)于c++編譯protobuf時(shí)提示LNK2001 無法解析的外部符號(hào)的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
在C++中實(shí)現(xiàn)aligned_malloc的方法
這篇文章主要介紹了在C++中實(shí)現(xiàn)aligned_malloc的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
C++實(shí)現(xiàn)LeetCode(113.二叉樹路徑之和之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(113.二叉樹路徑之和之二),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

