1. 程式人生 > >棧實現迷宮探索問題

棧實現迷宮探索問題

該死的資料結構實驗啊,難寫的要死。。。。555555翻了很多部落格,抄一個還是錯的,現在某些人的部落格真是沒良心,坑孩子啊55555,自己百般測試,終於是寫出來一個,親測有用

基本思路就是從入口開始,判斷當前座標是否可走,可走的話就入棧,然後按照上下左右四個方向依次嘗試,下一個節點能走就繼續嘗試,不能走就返回棧頂元素繼續嘗試下一個方向,然後入棧剛剛出棧的這個座標,當四個方向走完的時候,再次返回這個彈出來的座標就不能入棧了,繼續彈出一個座標,嘗試彈出來的這個座標的下一個方向。。。。依次迴圈,直到棧為空,或者走到終點。棧為空說明沒有出路。

還有個小心得哈,就是寫題之前好好想想要不要用指標,反正混著用很麻煩,這次就是把Position改成指標又改回來,反反覆覆,麻煩死了。

還有就是指標一定要malloc,要不然出錯的,這次就是老是吧該分配記憶體的沒分配,直接拿著個沒初始化的指標瞎比劃,浪費了很多時間,只有是變數的結構體才能直接建立而不用初始化。

#include <iostream>
#include <cstdio>
using namespace std;

#define STACKSIZE 100  //棧大小
#define ENTER_ROW 0   //入口行列
#define ENTER_COL 1
#define OUT_ROW 8    //出口行列
#define OUT_COL 9
#define N 10    //迷宮大小

typedef struct p   //座標
{
    int x, y;
}Position;

typedef struct d
{
    Position position;
    int dictionary;    //記錄走過了多少方向
}DicPosition;

typedef struct s    //定義棧
{
    DicPosition array[STACKSIZE];
    int rear;
    int size;
}*Stack;

//定義迷宮
int mazing[N][N] = {
        {2,0,2,2,2,2,2,2,2,2},//0
        {2,0,0,2,0,0,0,2,0,2},//1
        {2,0,0,2,0,0,0,2,2,2},//2
        {2,0,0,0,0,2,2,0,0,2},//3
        {2,0,2,2,2,0,2,0,2,2},//4
        {2,0,0,0,2,0,0,0,0,2},//5
        {2,0,2,0,0,0,2,0,0,2},//6
        {2,0,2,2,2,0,2,2,0,2},//7
        {2,2,0,0,0,0,0,0,0,0},//8
        {2,2,2,2,2,2,2,2,2,2} //9
};

Stack initStack();      //初始化棧
bool isEmpty(Stack stack);      //空
bool isFull(Stack stack);       //滿
bool push(Stack stack, DicPosition dicPosition); //入棧
int pop(Stack stack, DicPosition &dicPosition);    //出棧
bool check(Position position);   //檢查這個座標是否可走
Position nextPosition(Position position, int direction); //獲得下一個可走座標


int main() {
    Stack stack = initStack();
    Position position;
    position.x = ENTER_ROW;
    position.y = ENTER_COL;
    DicPosition dicPosition;
    dicPosition.position.x = position.x;
    dicPosition.position.y = position.y;
    dicPosition.dictionary = 0;
    push(stack, dicPosition);    //入口一定能走
    bool flag = false;
    while (!isEmpty(stack))
    {
        if (check(position))     //說明能走,就賦值為10,入棧,繼續下一步
        {
            if (flag)        //為維持不空,只對首元素入棧時起作用
            {
                dicPosition.position = position;
                dicPosition.dictionary = 0;
                push(stack, dicPosition);
            }
            mazing[position.x][position.y] = 10;
            flag = true;

            //到達出口
            if (position.x == OUT_ROW && position.y == OUT_COL)
                break;

            position = nextPosition(position, 1);        //繼續探索下一個座標
            stack->array[stack->rear-1].dictionary = 1;     //棧頂元素走過一個方向,計數為1
        } else  //不能走,就取出當前棧頂元素,嘗試下一個方向
        {
            if (!isEmpty(stack))    //棧不空
            {
                pop(stack, dicPosition);
                while (dicPosition.dictionary == 4 && !isEmpty(stack))   //檢查是否四個方向都走過
                {
                    mazing[dicPosition.position.x][dicPosition.position.y] = 9;  //標記9是已經走過
                    pop(stack, dicPosition);
                }

                if (dicPosition.dictionary < 4)   //四個方向沒走完,繼續下一個方向
                {
                    position = nextPosition(dicPosition.position, dicPosition.dictionary+1);
                    dicPosition.dictionary++;
                    push(stack, dicPosition);     //上面彈出的棧頂元素沒有走完四個方向,重新入棧
                }
            }
        }
    }

    for (int i=0; i<N; i++)
    {
        for (int j=0; j<N; j++)
        {
            printf("%3d ", mazing[i][j]);
        }
        printf("\n");
    }

    free(stack);

    return 0;
}

Stack initStack()
{
    Stack stack = (Stack) malloc(sizeof(s));
    stack->rear = 0;
    stack->size = STACKSIZE;
    return stack;
}

bool isEmpty(Stack stack)
{
    return stack->rear == 0;
}

bool isFull(Stack stack)
{
    return stack->rear == STACKSIZE - 1;
}

bool push(Stack stack, DicPosition dicPosition)
{
    if (isFull(stack))
    {
        printf("棧滿!");
        return false;
    } else
    {
        stack->array[stack->rear] = dicPosition;
        stack->rear++;
    }
}

int pop(Stack stack, DicPosition &dicPosition)
{
    if (isEmpty(stack))
    {
        printf("棧空");
        return 0;
    } else
    {
        stack->rear--;
        dicPosition = stack->array[stack->rear];
    }
}

bool check(Position position)
{
    if (mazing[position.x][position.y] != 0)    //走不通
        return false;
    if (position.x < 0 || position.x >= N)   //行越界
        return false;
    if (position.y < 0 || position.y >= N)   //列越界
        return false;
    return true;
}

Position nextPosition(Position position, int direction)
{
    Position temp = position;
    temp.x = position.x;
    temp.y = position.y;
    switch (direction)
    {
        case 1:{
            temp.x -= 1; //上
            break;
        }
        case 2:{
            temp.x += 1;   //下
            break;
        }
        case 3:{
            temp.y -= 1;   //左
            break;
        }
        case 4:{
            temp.y += 1;  //右
            break;
        }
    }
    return temp;
}