1. 程式人生 > >(資料結構)棧_迷宮求解(嚴蔚敏P50) _模仿

(資料結構)棧_迷宮求解(嚴蔚敏P50) _模仿

一般方法(遍歷搜尋,尋求最優):

#include"ds.h"

#define MAX_COLUM 10  //迷宮最大列數
#define MAX_ROW 10  //迷宮最大行數
#define MAX_NUM 100  //儲存空間初始分配量,估計實際量設定
int NUM[MAX_NUM]; //記錄curstep
int NUM_CURSTEP=0; //實際curstep個數

/*用陣列表示資料結構書中的迷宮,1表示牆壁,0表示通道*/
int a[MAX_ROW][MAX_COLUM]={
	{1,1,1,1,1,1,1,1,1,1},
	{1,0,0,1,0,0,0,1,0,1},
	{1,0,0,1,0,0,0,1,0,1},
	{1,0,0,0,0,1,1,0,0,1},
	{1,0,1,1,1,0,0,0,0,1},
	{1,0,0,0,1,0,0,0,0,1},
	{1,0,1,0,0,0,1,0,0,1},
	{1,0,1,1,1,0,1,1,0,1},
	{1,1,0,0,0,0,0,0,0,1},
	{1,1,1,1,1,1,1,1,1,1}
	
};

/*結構體表示座標位置*/
typedef struct Pos{
	int x;
	int y;
}Pos;

Pos Begin={1,1},End={8,8};  //設定迷宮的進口和出口
int curstep=1;

/*最終輸出結果*/
void print()
{
	int i,j;
	for(i=0;i<MAX_ROW;i++)
	{
		for(j=0;j<MAX_COLUM;j++)
		printf("%d  ",a[i][j]);  //空格為了方便檢視陣列
		printf("\n");
	}
}

void Save(int curstep) //記錄每次成功搜尋所需的步數
{
	NUM[NUM_CURSTEP++]=curstep;
}

int Sort(int NUM[]) //獲得最優步數
{
	int i ,j ,temp;
	for(i=0;i<NUM_CURSTEP;i++) //冒泡排列,遞增排序
		for(j=i+1;j<NUM_CURSTEP;j++)
		{
			if(NUM[i]>NUM[j])
			{
				temp=NUM[i];
			    NUM[i]=NUM[j];
				NUM[j]=temp;
			}
		}
		return NUM[0];
}

/*路徑搜尋*/
void Path(Pos position ,int curstep)
{
    int i;
	Pos next_position;
	Pos direction[4]={{0,1},{1,0},{0,-1},{-1,0}}; //搜尋方向依次為東南西北

	for(i=0;i<4;i++)
	{
		next_position.x=position.x+direction[i].x;
		next_position.y=position.y+direction[i].y;

		if(a[next_position.x][next_position.y]==0)
		{
			a[next_position.x][next_position.y]=++curstep;
			if(next_position.x!=End.x||next_position.y!=End.y)
				Path(next_position,curstep);
			else
			{
				print();
                printf("\n");
				Save(curstep);
			}
			a[next_position.x][next_position.y]=0;
			curstep--;
		} //if end
	} //for end
}

int main()
{
	int Minstep=0;
	printf("迷宮路徑如下:\n");

	a[Begin.x][Begin.y]=1;
    Path(Begin ,1);

	Minstep=Sort(NUM);

	printf("迷宮搜尋可行方案總共 %d 組\n",NUM_CURSTEP);
    printf("迷宮搜尋最優步數為: %d 步\n",Minstep);

	return 0;
}


利用棧(只尋找一條路徑,且很大可能性不是最優路徑,不推薦,只是為了熟悉棧):

#include"ds.h"
#define MAX_ROW 7  //迷宮最大行數
#define MAX_COLUMN 7  //迷宮最大列數
#define STACK_INIT_SIZE 10
#define STACK_INCREMENT 2

typedef struct{  //迷宮座標位置
	int x;
	int y;
}Pos;

typedef struct{  //棧的元素
	int ord;  //路徑上的序號
	Pos seat;  //座標位置
	int di;  //下一步行走的方向
}SElemType;

typedef struct{  //棧
	SElemType *base;
	SElemType *top;
    int stacksize;
}SqStack;

/*用陣列表示資料結構書中的迷宮,1表示牆壁,0表示通道*/
int a[MAX_ROW][MAX_COLUMN] = {
	{2, 2, 2, 2, 2, 2, 2}, 
	{2, 0, 0, 0, 0, 0, 2}, 
	{2, 0, 2, 0, 2, 0, 2}, 
	{2, 0, 0, 2, 0, 2, 2}, 
	{2, 2, 0, 2, 0, 2, 2}, 
	{2, 0, 0, 0, 0, 0, 2}, 
	{2, 2, 2, 2, 2, 2, 2}	
}; 

Pos Begin={1,1},End={5,5};  //設定迷宮入口和出口
int curstep=1;  //步數
SqStack S;  //定義一個全域性順序棧

/*構造一個空棧*/
void InitStack(SqStack &S)
{
	S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
	if(!S.base) exit(OVERFLOW);

	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
}

/*判斷一個棧是否為空棧,是返回1,不是返回0*/
int StackEmpty(SqStack S)
{
	if(S.base==S.top)
		return 1;
	else 
		return 0;
}

/*插入e為新的棧頂元素*/
void Push(SqStack &S ,SElemType e)
{
	if((S.top-S.base)>=S.stacksize)
	{
		S.base=(SElemType*)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType));
	    if(!S.base) exit(OVERFLOW);

	    S.top=S.base+S.stacksize;
        S.stacksize+=STACK_INCREMENT;
	}
	*S.top++=e;
}

/*若棧不為空,則用e刪除棧頂元素,並返回OK,否則返回ERROR*/
int Pop(SqStack &S ,SElemType &e)
{
	if(S.top==S.base)
		return ERROR;

	e=*--S.top;
	return OK;
}

/*輸出走迷宮的路徑*/
void FootPrint()
{
	int i,j;
	for(i=0;i<MAX_ROW;i++)
	{
		for(j=0;j<MAX_COLUMN;j++)
			printf("%d ",a[i][j]);  //空格為了觀看方便
		printf("\n");
	}
}

/*求當前位置的下一步*/
void NextStep(Pos &seat ,int di)
{
	Pos direction[4]={{0,1},{1,0},{0,-1},{-1,0}};  //方向依次為東南西北

	seat.x+=direction[di].x;
	seat.y+=direction[di].y;
}

/*搜尋迷宮路徑,只能搜尋一條路徑,且不一定是最優路徑*/
/*若能求得一條路徑則返回TURE,否則返回FALSE*/
int Path(Pos Begin ,Pos End)
{
	Pos CurPos;
	SElemType e;
	InitStack(S);
	CurPos=Begin;  //將最初位置設定為入口

	do
	{
		if(a[CurPos.x][CurPos.y]==0)  //此時的位置為通路
		{
			a[CurPos.x][CurPos.y]=curstep;
			e.ord=curstep;
			e.seat=CurPos;
			e.di=0;

			Push(S,e);
			curstep++;

			if(CurPos.x==End.x&&CurPos.y==End.y)
				return TRUE;

			NextStep(CurPos,e.di);
		}  //if(a[CurPos.x][CurPos.y]==0) end
		else
		{
			if(!StackEmpty(S))
			{
				Pop(S,e);
				curstep--;
				while(e.di==3&&!StackEmpty(S))
				{
					a[e.seat.x][e.seat.y]=-1;
					Pop(S,e);
					curstep--;
				}  //while(e.di==3&&!StackEmpty(S)) end
				if(e.di<3)
				{
					e.di++;
					Push(S,e);
					curstep++;
					CurPos=e.seat;
					NextStep(CurPos,e.di);
				}  //if(e.di<3)
			}  //if(!StackEmpty(S)) end
		}  //else end
	} while(!StackEmpty(S)); //do end
	return FALSE;
}

int main()
{
	if(Path(Begin ,End))
	{
		printf("路徑如下:\n");
        FootPrint();
	}
	else
	{
		printf("此迷宮走不通\n");
	}
	return 0;
}