【資料結構】簡單不帶環迷宮的實現(用棧實現)
一.用棧來實現簡單的迷宮
1. 迷宮:
回溯法:對一個包括有很多個結點,每個結點有若干個搜尋分支的問 題,把原問題分解為若干個子問題求解的演算法;當搜尋到某個結點發 現無法再繼續搜尋下去時,就讓搜尋過程回溯(回退)到該節點的前一 個結點,繼續搜尋該節點外的其他尚未搜尋的分支;如果發現該結點 無法再搜尋下去,就讓搜尋過程回溯到這個結點的前一結點繼續這樣 的搜尋過程;這樣的搜尋過程一直進行到搜尋到問題的解或者搜尋完 了全部可搜尋分支沒有解存在為止。
2.迷宮實現的簡單步驟
(1.) 首先要初始化迷宮
(2.) 檢測合法的迷宮入口(要求入口必須在迷宮的邊界且為一 )
(3.)走迷宮(步驟是上.左.右.下)把每步走的路程賦值為2如果走的路行不通則標記為3
(4.)檢測是否為迷宮出口(在邊界且不和入口相等)
在實現程式碼時一定要注意前置標頭檔案的宣告
3.實現迷宮的程式碼
stack.h
#pragma once #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> extern struct Position; typedef struct Position DataType; typedef struct Stack { DataType *arr;//指向動態空間的指標 int capacity;//空間總容量 int size;//有效元素個數 }Stack, *PStack; // 棧的初始化 void StackInit(PStack ps, int capacity); // 入棧 void StackPush(PStack ps, DataType data); // 出棧 void StackPop(PStack ps); // 獲取棧頂元素 DataType StackTop(PStack ps); // 獲取棧中元素個數 int StackSize(PStack ps); // 檢測棧是否為空 int StackEmpty(PStack ps);
Maze.h
#pragma once #define MAX_ROW 6 #define MAX_COL 6 typedef struct Position { int _x; int _y; }Position; typedef struct Maze { int _map[MAX_ROW][MAX_COL]; }Maze, *PMaze; //1. 用棧對簡單迷宮進行求解,迷宮只有一個出口 //採用迴圈方式實現 // 棧的初始化 void InitMaze(PMaze pm, int map[][MAX_COL]); // 檢測入口是否為有效入口 int IsValidEntry(PMaze pm, Position entry); // 檢測cur位置是否是通路 int IsPass(PMaze pm, Position cur); // 檢測Cur是否在出口 int IsExit(PMaze pm, Position cur, Position entry); // 走迷宮 void PassMaze(PMaze pm, Position entry, PStack ps); // 列印迷宮 void PrintMaze(PMaze m, int map[][MAX_COL]);
stack.c
#include "stack.h"
#include "Maze.h"
//初始化棧,有效元素清空,分配起始空間
void StackInit(PStack ps, int capacity)
{
if (NULL == ps)
return;
ps->arr = (DataType *)malloc(sizeof(DataType)*capacity);
if (NULL == ps->arr)
{
printf("申請空間失敗!!!\n");
return;
}
ps->capacity = capacity;//空間容量改變
ps->size = 0;//有效元素清空
}
void AddCapacity(PStack ps)
{
if (NULL == ps)
return;
ps->arr = (DataType *)realloc(ps->arr, sizeof(DataType)*(ps->capacity) * 2);//擴增位原空間大小二倍
if (NULL == ps->arr)
{
printf("空間擴增失敗!!!\n");
return;
}
ps->capacity = 2 * (ps->capacity);
}
//列印棧
void PrintStack(PStack ps)
{
int i = 0;
if (NULL == ps)
return;
for (; i < ps->size; i++)
{
printf("%d ", ps->arr[i]);
}
printf("\n");
}
//入棧,就是對錶進行尾插
void StackPush(PStack ps, DataType data)
{
if (NULL == ps)
return;
if (ps->size == ps->capacity)//說明空間已滿,要申請空間
AddCapacity(ps);
ps->arr[ps->size] = data;
ps->size++;
}
//出棧
void StackPop(PStack ps)
{
if (NULL == ps)
return;
if (ps->size == 0)
{
printf("棧已空,操作失敗!!!\n");
return;
}
ps->size--;
}
// 獲取棧頂元素,棧頂就是表的尾部
DataType StackTop(PStack ps)
{
if (NULL == ps)
{
printf("棧不存在!!!\n");
return;
}
if (ps->size == 0)
{
printf("棧已空!!!\n");
return;
}
return ps->arr[ps->size - 1];
}
// 獲取棧中元素個數
int StackSize(PStack ps)
{
if (NULL == ps)
{
printf("棧不存在!!!\n");
return 0;
}
return ps->size;
}
// 檢測棧是否為空
int StackEmpty(PStack ps)
{
if (NULL == ps)
{
printf("棧不存在!!!\n");
return 0;
}
if (ps->size)
return 0;
return 1;
}
Maze.c
#include "stack.h"
#include "Maze.h"
//列印迷宮
void PrintMaze(PMaze pm)
{
int i = 0;
assert(pm);
for (; i < MAX_ROW; ++i)
{
int j = 0;
for (; j < MAX_COL; ++j)
{
printf("%d ", pm->_map[i][j]);
}
printf("\n");
}
}
//迷宮初始化,就是將地圖中的值賦給迷宮
void InitMaze(PMaze pm, int map[][MAX_COL])
{
int i = 0;
assert(pm);
for (; i < MAX_ROW; ++i)
{
int j = 0;
for (; j < MAX_COL; ++j)
{
pm->_map[i][j] = map[i][j];
}
}
}
//檢測迷宮入口是否合法
int IsValidEntry(PMaze pm, Position entry)
{
assert(pm);
//必須位於迷宮邊界且值為1
if ((entry._x == 0 || entry._y == 0 || entry._x == MAX_ROW - 1
|| entry._y == MAX_COL - 1) && (pm->_map[entry._x][entry._y] == 1))
return 1;
return 0;
}
// 檢測cur位置是否是通路
int IsPass(PMaze pm, Position cur)
{
assert(pm);
//值為1且不能越界
if ((cur._x >= 0 && cur._x <= MAX_ROW - 1) &&
(cur._y >= 0 && cur._y <= MAX_COL - 1) &&
pm->_map[cur._x][cur._y] == 1)
return 1;
return 0;
}
// 檢測Cur是否在出口
int IsExit(PMaze pm, Position cur, Position entry)
{
assert(pm);
//出口位置就是處於邊界值為1且不能是入口
if ((cur._x == 0 || cur._y == 0 || cur._x == MAX_ROW - 1
|| cur._y == MAX_COL - 1) && (pm->_map[cur._x][cur._y] == 1)
&& ((cur._x != entry._x) || (cur._y != entry._y)))
return 1;
return 0;
}
//走迷宮
void PassMaze(PMaze pm, Position entry, PStack ps)
{
Position cur;
Position next;
assert(pm);
assert(ps);
//檢測入口是否合法
if (!IsValidEntry(pm, entry))
{
printf("迷宮入口不合法!!!\n");
return;
}
//走進入口,入棧
StackPush(ps, entry);
while (!StackEmpty(ps))
{
cur = StackTop(ps);
//在標記之前檢測要不然,cur位置值不為1
if (IsExit(pm, cur, entry))
{
pm->_map[cur._x][cur._y] = 2;
printf("已找到出口!!!\n");
return;
}
pm->_map[cur._x][cur._y] = 2;
//依次判斷上下左右是否可以走通
//上
next = cur;
next._x -= 1;
//判斷是否可以走通
if (IsPass(pm, next))
{
StackPush(ps, next);
continue;
}
//左
next = cur;//如果走到這,next值已經變了,所以要重新賦值
next._y -= 1;
if (IsPass(pm, next))
{
StackPush(ps, next);
continue;
}
//右
next = cur;
next._y += 1;
if (IsPass(pm, next))
{
StackPush(ps, next);
continue;
}
//下
next = cur;
next._x += 1;
if (IsPass(pm, next))
{
StackPush(ps, next);
continue;
}
//如果上下左右都不能走通,那麼說明cur走錯了,標記為3,出棧
pm->_map[cur._x][cur._y] = 3;
StackPop(ps);
}
//走到這,說明找不到迷宮出口
printf("迷宮沒有出口!!!\n");
}
test.c
#include "stack.h"
#include "Maze.h"
#include <windows.h>
void TestMaze(PStack ps)
{
int i = 0;
Position entry;
Maze m;
PMaze pm = &m;
StackInit(ps, 10);
int map[6][6] = { { 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 0 },
{ 0, 0, 1, 0, 1, 1 },
{ 0, 0, 1, 0, 0, 0 } };
InitMaze(pm, map);
PrintMaze(pm, map);
entry._x = 5;
entry._y = 2;
PassMaze(pm, entry, ps);
printf("\n");
PrintMaze(pm, map);
}
int main()
{
Stack s;
PStack ps = &s;
TestMaze(ps);//測試迷宮
system("pause");
return 0;
}
相關推薦
【資料結構】簡單不帶環迷宮的實現(用棧實現)
一.用棧來實現簡單的迷宮1. 迷宮:回溯法:對一個包括有很多個結點,每個結點有若干個搜尋分支的問 題,把原問題分解為若干個子問題求解的演算法;當搜尋到某個結點發 現無法再繼續搜尋下去時,就讓搜尋過程回溯(回退)到該節點的前一 個結點,繼續搜尋該節點外的其他尚未搜尋的分支;
【資料結構】4.1串的基本操作(附程式碼實現)
串的基本操作有: 賦值 連線 比較 清空 求子串 具體程式碼如下 #include <stdio.h> #include<malloc.h> #include<stdlib.h> #include<stri
【資料結構】二叉樹的相關操作(待更)
#include "stdio.h" #include "stdlib.h" typedef struct node { char data; struct node *rchild,*lchild; }bintnode; typedef bintnode *bintree;//指向該結構體
【資料結構】帶有尾指標的連結串列:連結串列實現佇列
前面寫了用動態陣列實現佇列,現在我將用帶有尾指標的連結串列實現佇列。 我們知道佇列需要在兩端進行操作,如果是以普通連結串列進行底層實現的佇列,在入隊時需要找到最後一個節點才能進行新增元素,這樣相當於遍歷一遍連結串列,從而造成巨大的時間浪費。 為了解決這個問題,我們引入了尾
【資料結構】1-2 約瑟夫環問題
這裡放出兩種不同的程式碼,一個是老師給的(較為複雜),還有一個是自己寫的。 自己寫的: #include<iostream> using namespace std; struct Node { int data; //資料單元 Node *link
【資料結構】實現順序表以及簡單的時間複雜度分析
最近在學資料結構,接下來一段時間我將用java來實現所學的各種資料結構,以加深自己的印象。 線性表包括順序表和連結串列,其實順序表就是動態陣列,下面我將二次封裝實現屬於自己的動態陣列。 -------------------------------------------
【資料結構】棧的簡單實現
我們都知道棧(Stack)是限制僅在表的一段進行插入和刪除運算的線性表 1、通常稱插入、刪除的這一端為棧頂(Top),另一端為棧底(Bottom) 2、當表中沒有元素時被稱為空棧 3、棧為先進後出(Last In First Out)的線性表,簡稱LIFO 棧的修改總
【資料結構】求簡單迷宮是否存在路徑(遞迴和非遞迴版)
求簡單迷宮是否存在路徑 程式碼中用到的棧程式碼如下: stack.h #pragma once #include<stdio.h> #include<stddef.h> #include"Maze.h" typedef Pos SeqType
【資料結構】資料結構C語言的實現(簡單二叉樹)
簡單二叉樹 /* * 二叉樹 */ #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FAL
【資料結構】28、判斷連結串列是否有環
因為最近小米電話面試被問到如何判斷一個連結串列是否有環,那今天正好實現以下這個演算法 1.連結串列 package y2019.Algorithm.LinkedList; /** * @ProjectName: cutter-point * @Package: y2019
【資料結構】31、hashmap=》resize 擴容,不測不知道,一測嚇一跳
來來來,今天就跟hashmap槓到底。。。 不要叫我槓精了,主要是還是被問到hashmap的時候,我並不能很清晰明瞭得告知這種資料結構到底是一個什麼構造,裡面細節並不瞭解 既然這樣,我們就把他解析一波,今天這篇也算是hashmap的收官之作了,主要用來紅黑樹部分我之前有博文寫過,但是不用深究  
【java 資料結構】還不會二叉樹?一篇搞定二叉樹
二叉樹是我們常見的資料結構之一,在學習二叉樹之前我們需要知道什麼是樹,什麼是二叉樹,本篇主要講述了二叉樹,以及二叉樹的遍歷。 你能get到的知識點? 1、樹的介紹 2、二叉樹的介紹 3、二叉樹遍歷的四種方法 4、牛客題目:反轉二叉樹 目錄你能get到的知識點?一、知識預備1、樹2、樹的相關術語介紹1、二叉樹2
【資料結構】帶權並查集
# 目錄 + 簡介 + 詳細介紹 + 例題 ## 簡介 顧名思義,就是在維護集合關係的樹中新增邊權的並查集,這樣做可以維護更多的資訊。 引入題目:https://www.luogu.com.cn/problem/P2024 比如這道題,如果使用普通的並查集則無法處理,因為普通的並查集只能夠刻畫兩個物品是
【資料結構】—— 1、不要小瞧陣列
2-1、 使用Java中的陣列 2-2 二次封裝屬於我們自己的陣列 2-3 向陣列中新增元素 2-4 陣列中查詢元素和修改元素 2-5 包含,搜尋和刪除 2-6 使用泛型 2-7 動態陣列 2-8 簡單的複雜度分析 2-9 均攤複雜度和防止複雜度的震盪
【資料結構】【多項式連結串列實現相加】
#include<bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 1006; struct node { double coef; int exp; struct n
【資料結構】【合併兩個有序連結串列】
#include<stdio.h> #include<string.h> #include<stdlib.h> const int maxn = 1e5 + 5; struct node { int num; struct node *next; }; s
雙棧實現整數(支援大於十的整數)計算器【資料結構】
通過棧的操作實現簡單的計算器 首先定義兩個棧,一個叫s_num用來存放運算元,另一個叫s_opt用來存放操作符。 再定義一個字元陣列用來存放輸入的表示式,初始化為0; 當表示式的字元不為‘/0’時,或者操作符棧中不為空的時候,就要一直執行程式! 在執行的時候做兩個判斷,輸入的不是數字
【資料結構】【二】陣列實現的線性表(線性表的順序儲存結構)
資料結構 陣列實現線性表 通過陣列實現了一個簡單的線性表 功能: 在陣列尾部新增元素 在陣列指定位置新增元素 根據下標獲取元素 根據下標刪除元素 根據元素刪除元素 獲取當前陣列長度 判斷當前陣列是否為空 列印陣列元素 public
【資料結構】【一】基本概念
資料基本概念: 資料:描述客觀事物的符號,是計算機中可以操作的物件,是能被計算機識別,並輸入給計算機處理的符號集合.資料元素:是組成資料的,有一定意義的基本單位,在計算機中通常作為整體處理.比如人,牛,羊.資料項:一個數據元素可以由若干個資料項組成,比如人可以有眼,耳,鼻,也可有姓名,年齡,地址
【資料結構】【線段樹】2018國慶三校聯考D5T3
題意: 分析: 有一個顯然的暴力方法: 對每個詢問,從左往右做一次,記錄字首和,當某個位置字首和為負後,則刪去當前點。再從右往左做一次。 考慮使這個過程變得高效: 可以將詢問按左端點從右往左排序,然後用棧依次處理每個在從左往右考慮時是否需要刪除。 再利用線段樹,求