1. 程式人生 > >資料結構C語言版(第二章迷宮)

資料結構C語言版(第二章迷宮)

轉自未空blog

 

//我剛開始對STACK的記憶體分配那有點問題,後來用這個程式碼除錯了下,感覺有點明白了,   地址由高到低分配,然後程式碼中的base和top剛開始指向地址最低的地方,記憶體不夠時重新在原有基礎上新增記憶體,top指向原有的棧頂,然後繼續存入資料

/*
#include<stdio.h>
#include<iostream>
#include<limits.h>
#include<stdlib.h>
#include<iomanip>
#define STACK_INIT_SIZE 1
#define STACKINCREMENT 10
#define OK 1
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define ERROR 0
#define MAXLENGTH 25;
using namespace std;
typedef  int Status;
typedef int MazeType[25][25];
typedef int ElemType;
struct PosType{
    int x;
    int y;
};
struct SElemType{									//這個是棧的元素
    int ord;				//通道塊的序號
    PosType seat;			//通道塊在迷宮的座標位置
    int direc;				//方向
};
PosType curpos;										//定義當前位置
PosType direction[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };				//定義四個方向
typedef struct{
    SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;
Status InitStack(SqStack &L)		//構建一個棧
{

    L.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));		//動態分配記憶體
    if (!L.base) exit(OVERFLOW);
    L.top = L.base;

    cout << endl << L.top << "  " << L.base << endl << endl;
    L.stacksize = STACK_INIT_SIZE;														//初始化長度為0
    return OK;
}
Status Push(SqStack &L, SElemType &e)					//棧中插入元素e
{

    if(L.top - L.base >= L.stacksize)
    {
        cout << "先前" << L.base << "&" << L.top << endl;
        L.base = (SElemType*)realloc(L.base, (L.stacksize+1)* sizeof(SElemType));
        cout <<"擴大記憶體" << L.base << endl;
        cout << L.stacksize << endl;
    L.top = L.base + L.stacksize;
        cout << " 22222222"<< L.top << endl;
        L.stacksize += 1;
    }

    *L.top++ = e;


    //L.top++;
//    L.stacksize++;
    return OK;
}

Status Pop(SqStack &L, SElemType &e)
{
    if (L.top == L.base) return ERROR;
    e = *--L.top;
//    cout << L.top << "測試"  << endl;
//    L.stacksize--;
    return OK;
}
Status IsStackEmpty(SqStack S)
{
    if (S.top == S.base) return true;
    else return false;
}
MazeType maze;
int i, j, m, n;					//m,n表示行數列數
void PrintMaze()				//輸出迷宮
{
    int i, j;
    for (i = 0; i < m; i++){
        for (j = 0; j < n; j++)
            cout << setw(3) << maze[i][j];
        cout << endl;
    }
}
PosType Start, End;									//入口和出口分別用begin 和and 表示
Status InitMaze()								//設定迷宮
{
    cin >> m >> n;								//迷宮m行n列
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++){
            maze[i][j] = 1;							//通道用1表示
        }
    for (i = 0; i < n; i++){
        maze[0][i] = 0;								//迷宮0表示牆
        maze[m - 1][i] = 0;							//第一行加最後一行全部0
    }
    for (j = 0; j < m; j++){						//第一列最後一列全部0
        maze[j][0] = 0;
        maze[j][n - 1] = 0;
    }
    cout << "迷宮的初始結構如下:   " << endl;
    PrintMaze();
    cout << "請輸入迷宮的牆數:" << endl;
    int num;
    int x1, y1;
    cin >> num;
    cout << "請輸入迷宮的牆的座標:" << endl;
    for (i = 0; i < num; i++){
        cin >> x1 >> y1;
        maze[x1][y1] = 0;
    }
    cout << "請輸入入口的座標:" << endl;
    cin >> Start.x >> Start.y;
    cout << "請輸入出口的座標: " << endl;
    cin >> End.x >> End.y;
    PrintMaze();
    return 0;
}
int curstep = 1;								//走到第幾個格子了,初值在入口處為一
Status CanPass(PosType b)
{
    cout << maze[b.x][b.y] << endl;
    if (maze[b.x][b.y] == 1)
        return OK;
    else return ERROR;
}
void FootPrint(PosType b)				//把某個點b變成足跡
{
    maze[b.x][b.y] = curstep;				//走過以後做個標記-1
}
Status NextPos(PosType &e, int direc)
{
    curpos.x += direction[direc].x;
    curpos.y += direction[direc].y;
    return OK;
}
Status MarkPrint(PosType b)
{
    maze[b.x][b.y] = -1;
    return OK;
}
Status MazePath(PosType start, PosType end)
{
    curpos = start;								//初始化位置
    SqStack S;
    InitStack(S);
    cout << S.base << "    " << S.stacksize << "    " << S.top << endl;
    SElemType e;
    do{
        if (CanPass(curpos)){					//如果當前位置能通過
            FootPrint(curpos);					//那就在這個點留下足跡
            e.ord = curstep;					//棧元素e的編號為curstep
            e.seat = curpos;					//通道塊在迷宮的座標位置為當前位置
            e.direc = 0;						//然後把方向初始化為向東
            Push(S, e);
            cout << "Push" <<S.top << "測試"  << endl;//滿足要求e入棧
            curstep++;
            cout << curstep << "	" << curpos.x << "," << curpos.y << endl;
            if (curpos.x == end.x&&curpos.y == end.y)
                return TRUE;
            NextPos(curpos, e.direc);
        }
        else{									//當前位置不能通過
            if (!IsStackEmpty(S)){
                Pop(S, e);
                curstep--;
                while (e.direc == 3 && !IsStackEmpty(S))				//前一個位置在最後一個方向且不是空棧
                {
                    MarkPrint(e.seat);
                    Pop(S, e);
                    cout << "POP" << S.top << "測試"  << endl;
                    curstep--;
                }
                if (e.direc < 3){
                    e.direc++;
                    Push(S, e);
                    curstep++;
                    curpos = e.seat;
                    NextPos(curpos, e.direc);
                }
            }
        }
    } while (!IsStackEmpty(S));
    return false;
}
int main()
{
    InitMaze();
    if (MazePath(Start, End)){
        cout << "迷宮的一條路徑如下:" << endl;
        PrintMaze();
    }
    else cout << "Error!" << endl;
    return 0;
}*/

 

這個當時有個小細節有錯.....改了挺長時間的

#include<stdio.h>
#include<iostream>
#include<limits.h>
#include<stdlib.h>
#include<iomanip>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define ERROR 0
#define MAXLENGTH 25;
using namespace std;
typedef  int Status;
typedef int MazeType[25][25];
typedef int ElemType;
struct PosType{
	int x;
	int y;
};
struct SElemType{									//這個是棧的元素
	int ord;				//通道塊的序號
	PosType seat;			//通道塊在迷宮的座標位置
	int direc;				//方向
};
PosType curpos;										//定義當前位置
PosType direction[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };				//定義四個方向
typedef struct{
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;
Status InitStack(SqStack &L)		//構建一個棧
{

	L.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));		//動態分配記憶體
	if (!L.base) exit(OVERFLOW);
	L.top = L.base;

L.stacksize = 0;														//初始化長度為0
return OK;
}
Status Push(SqStack &L, SElemType &e)					//棧中插入元素e
{
	*L.top++ = e;
	//L.top++;
	L.stacksize++;
	return OK;
}

Status Pop(SqStack &L, SElemType &e)
{
	if (L.top == L.base) return ERROR;
	e = *--L.top;
	L.stacksize--;
	return OK;
}
Status IsStackEmpty(SqStack S)
{
	if (S.top == S.base) return true;
	else return false;
}
MazeType maze;
int i, j, m, n;					//m,n表示行數列數
void PrintMaze()				//輸出迷宮
{
	int i, j;
	for (i = 0; i < m; i++){
		for (j = 0; j < n; j++)
			cout << setw(3) << maze[i][j];
		cout << endl;
	}
}
PosType Start, End;									//入口和出口分別用begin 和and 表示
Status InitMaze()								//設定迷宮
{
	cin >> m >> n;								//迷宮m行n列
	for (i = 0; i < m; i++)
	for (j = 0; j < n; j++){
		maze[i][j] = 1;							//通道用1表示
	}
	for (i = 0; i < n; i++){
		maze[0][i] = 0;								//迷宮0表示牆
		maze[m - 1][i] = 0;							//第一行加最後一行全部0
	}
	for (j = 0; j < m; j++){						//第一列最後一列全部0
		maze[j][0] = 0;
		maze[j][n - 1] = 0;
	}
	cout << "迷宮的初始結構如下:   " << endl;
	PrintMaze();
	cout << "請輸入迷宮的牆數:" << endl;
	int num;
	int x1, y1;
	cin >> num;
	cout << "請輸入迷宮的牆的座標:" << endl;
	for (i = 0; i < num; i++){
		cin >> x1 >> y1;
		maze[x1][y1] = 0;
	}
	cout << "請輸入入口的座標:" << endl;
	cin >> Start.x >> Start.y;
	cout << "請輸入出口的座標: " << endl;
	cin >> End.x >> End.y;
	PrintMaze();
	return 0;
}
int curstep = 1;								//走到第幾個格子了,初值在入口處為一
Status CanPass(PosType b)
{
	cout << maze[b.x][b.y] << endl;
	if (maze[b.x][b.y] == 1) 
		return OK;
	else return ERROR;
}
void FootPrint(PosType b)				//把某個點b變成足跡
{
	maze[b.x][b.y] = curstep;				//走過以後做個標記-1
}
Status NextPos(PosType &e, int direc)
{
	curpos.x += direction[direc].x;
	curpos.y += direction[direc].y;
	return OK;
}
Status MarkPrint(PosType b)
{
	maze[b.x][b.y] = -1;
	return OK;
}
Status MazePath(PosType start, PosType end)
{
	curpos = start;								//初始化位置
	SqStack S;									
	InitStack(S);								
	cout << S.base << "    " << S.stacksize << "    " << S.top << endl;
	SElemType e;
	do{
		if (CanPass(curpos)){					//如果當前位置能通過
			FootPrint(curpos);					//那就在這個點留下足跡
			e.ord = curstep;					//棧元素e的編號為curstep
			e.seat = curpos;					//通道塊在迷宮的座標位置為當前位置
			e.direc = 0;						//然後把方向初始化為向東
			Push(S, e);							//滿足要求e入棧
			curstep++;
			cout << curstep << "	" << curpos.x << "," << curpos.y << endl;
			if (curpos.x == end.x&&curpos.y == end.y)
				return TRUE;
			NextPos(curpos, e.direc);
		}
		else{									//當前位置不能通過
			if (!IsStackEmpty(S)){
				Pop(S, e);
				curstep--;
				while (e.direc == 3 && !IsStackEmpty(S))				//前一個位置在最後一個方向且不是空棧
				{
					MarkPrint(e.seat);
					Pop(S, e);
					curstep--;
				}
				if (e.direc < 3){
					e.direc++;
					Push(S, e);
					curstep++;
					curpos = e.seat;
					NextPos(curpos, e.direc);
				}
			}
		}
	} while (!IsStackEmpty(S));
	return false;
}
int main()
{
	InitMaze();
	if (MazePath(Start, End)){
		cout << "迷宮的一條路徑如下:" << endl;
		PrintMaze();
	}
	return 0;
}