1. 程式人生 > >【資料結構】簡單不帶環迷宮的實現(用棧實現)

【資料結構】簡單不帶環迷宮的實現(用棧實現)



一.用棧來實現簡單的迷宮

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

題意: 分析: 有一個顯然的暴力方法: 對每個詢問,從左往右做一次,記錄字首和,當某個位置字首和為負後,則刪去當前點。再從右往左做一次。 考慮使這個過程變得高效: 可以將詢問按左端點從右往左排序,然後用棧依次處理每個在從左往右考慮時是否需要刪除。 再利用線段樹,求