數據結構之迷宮問題

迷宮結構如下:

定義三個結構體,

#define _size 100		//對該迷宮,100個夠用了
#define add_size 10		//每次要增加的大小
#define endFlag NULL	//出錯時返回的標誌
#define row 8			//迷宮的行的大小,對應i
#define col 8			//迷宮的列的大小,對應j

typedef struct _list{
	int data;
	struct _list *next;
}list,*LinkList;


//一個節點的結構
typedef struct{
	int x;				//當前位置的x
	int y;				//當前位置的y
	int status;			//0表示沒遍歷過,1表示已經遍歷過,-1表示不能通過
	LinkList drit;		//周圍可以遍歷的方向,1,2,3,4分別表示東南西北,0表示全部遍歷過
}*node,_Node;		



typedef struct{
	node *base;
	node *top;
	int size;
}*stack,st;	

int m[row][col]			//迷宮佈局,全局變量
	= {
		0,0,1,0,0,0,1,0,
		0,0,1,0,0,0,1,0,
		0,0,0,0,1,1,0,0,
		0,1,1,1,0,0,0,0,
		0,0,0,1,0,0,0,0,
		0,1,0,0,0,1,0,0,
		0,1,1,1,0,1,1,0,
		1,0,0,0,0,0,0,0
	};


全部代碼如下:

#include "stdio.h"
#include "stdlib.h"

/*
 * 用棧解決迷宮問題
*/
#define _size 100		//對該迷宮,100個夠用了
#define add_size 10		//每次要增加的大小
#define endFlag NULL	//出錯時返回的標誌
#define row 8			//迷宮的行的大小,對應i
#define col 8			//迷宮的列的大小,對應j

typedef struct _list{
	int data;
	struct _list *next;
}list,*LinkList;


//一個節點的結構
typedef struct{
	int x;				//當前位置的x
	int y;				//當前位置的y
	int status;			//0表示沒遍歷過,1表示已經遍歷過,-1表示不能通過
	LinkList drit;		//周圍可以遍歷的方向,1,2,3,4分別表示東南西北,0表示全部遍歷過
}*node,_Node;		



typedef struct{
	node *base;
	node *top;
	int size;
}*stack,st;	

int m[row][col]			//迷宮佈局,全局變量
	= {
		0,0,1,0,0,0,1,0,
		0,0,1,0,0,0,1,0,
		0,0,0,0,1,1,0,0,
		0,1,1,1,0,0,0,0,
		0,0,0,1,0,0,0,0,
		0,1,0,0,0,1,0,0,
		0,1,1,1,0,1,1,0,
		1,0,0,0,0,0,0,0
	};

void InitList(LinkList *L);
void addList(LinkList L,int value);
void delList(LinkList *L);
void createNode(_Node _p[][col],int i,int j);//創立一個節點
void InitStack(stack *S);	//初始化棧
void DestroyStack(stack *S);//銷燬棧
void push(stack st,node *e);//插入元素
node* pop(stack st);		//彈出棧頂元素
node* getTop(stack st);		//獲得棧頂元素,並不刪除
int length(stack st);		//返回棧的元素個數
int isEmpty(stack st);		//是否爲空,c語言中沒有bool類型



void InitList(LinkList *L){
	(*L) = (LinkList)malloc(sizeof(list));
	if(!*L){
		printf("LinkList malloc failed!");
		return;
	}
	(*L)->data = 0;
	(*L)->next = NULL;
}

void addList(LinkList L,int value){
	LinkList p;

	while(1){
		if(L->next == 0){
			p = (LinkList)malloc(sizeof(list));
			p->data = 0;
			p->next = NULL;
			L->data = value;
			L->next = p;
			return;
		}	
		L = L->next;
	}
}

//刪除鏈表的頭節點
void delList(LinkList *L){
	LinkList p = (*L)->next;
	free(*L);
	*L = p;
}


void createNode(_Node _p[][col],int i,int j){

	node p = *( _p + i) + j;
	if(!p){
		printf("node malloc failed!");
		return;
	}

	p->x = i;
	p->y = j;
	p->status = 0;
	InitList(&p->drit);
	
	if( j < 7 &&  m[i][j+1] == 0)
		addList(p->drit,1);		
	if( i < 7 && m[i+1][j] == 0)
		addList(p->drit,2);	
	if( j > 0 && m[i][j-1] == 0)
		addList(p->drit,3);	
	if( i > 0 && m[i-1][j] == 0)
		addList(p->drit,4);	
}

void InitStack(stack *S){
	(*S) = (stack)malloc(sizeof(st));							//先爲棧的結構體分配空間
	(*S)->base = (node *)malloc(_size * sizeof(_Node) ); //再爲棧裏面的數組分配空間

	if(!*(*S)->base){
		printf("Stack malloc failed!");
		return;
	}
	(*S)->top = (*S)->base;
	(*S)->size = _size;
}

void DestroyStack(stack *S){
	node* temp;
	while((*S)->top > (*S)->base){
		temp = (*S)->top - 1;
		free((*S)->top);
		(*S)->top = temp;
	}
	free((*S)->base);
	free(*S);
}

void push(stack st,node *e){
	if( (st->top - st->base) >= st->size){	
		st->base = (node *)realloc(st->base,(st->size + add_size)*sizeof(_Node));
		st->size += add_size;
	}

	if(!st->base){
		printf("Remalloc failed!");
		return;
	}
	st->top++;
	*st->top = *e;  
	
}

node* pop(stack st){
	node* e;

	if(st->top == st->base)
		return endFlag;			//Error

	e = st->top--;			//equels to e= st->top;st->top--; 
	return e;
}

node* getTop(stack st){

	if(st->top == st->base)
		return endFlag;			//Error

	return st->top;		
}

int isEmpty(stack st){
	if(length(st) == 0)
		return 1;
	return 0;
}

int length(stack st){
	return st->top - st->base;
}


int main(){
	stack st;
	node p;
	_Node maze[row][col];	//創建結構體數組
	int i,j;

	for(i=0;i<row;i++)		//初始化結構體
		for(j=0;j<col;j++)
			 createNode(maze,i,j);

	InitStack(&st);
	p = &maze[0][0];
	push(st,&p);
	(*st->top)->status = 1;
	while(!isEmpty(st)){
		if((*st->top)->x == row -1 && (*st->top)->y == col -1)
			break;
		switch((*st->top)->drit->data){
		case 1:		//右
			delList(&(*st->top)->drit);		//將當前的右方向刪掉
			p = &maze[(*st->top)->x][(*st->top)->y + 1];
			if(p->status == 0){				//表示下一個點沒有在路徑裏面,或者不能走
				push(st,&p);
				(*st->top)->status = 1;
			}
			break;
		case 2:		//下
			delList(&(*st->top)->drit);
			p = &maze[(*st->top)->x + 1][(*st->top)->y];
			if(p->status == 0){
				push(st,&p);
				(*st->top)->status = 1;
			}
			break;
		case 3:		//左
			delList(&(*st->top)->drit);
			p = &maze[(*st->top)->x][(*st->top)->y - 1];
			if(p->status == 0){
				push(st,&p);
				(*st->top)->status = 1;
			}
			break;
		case 4:		//上
			delList(&(*st->top)->drit);
			p = &maze[(*st->top)->x - 1][(*st->top)->y];
			if(p->status == 0){
				push(st,&p);
				(*st->top)->status = 1;
			}
			break;
		default:	//沒有可以遍歷的方向
			(*st->top)->status = -1; //表示當前點不能走
			pop(st);
		}
	}

	if(isEmpty(st))
	{
		printf("沒有找到路徑\n");
		return 0;
	}
	i =1,j=5;
	while(!isEmpty(st)){
		printf("(%d,%d) <- ",(*st->top)->x,(*st->top)->y);
		pop(st);
		if(i++%j == 0)
			printf("\n");
	}
	printf("enter\n");
	return 0;
}

程序輸出的路徑如下:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章