棧的簡單應用

      本文是對順序棧的兩個簡單應用(數制轉換、迷宮求解)進行練習。代碼如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define STACK_INIT_SIZE 10
#define STACK_INCREMENT 10

// typedef int ElemType;

typedef struct {
	int x;			// 橫座標
	int y;			// 縱座標
}POS;

typedef struct {
	int sno;		// 序號
	POS seat;		// 位置座標
	int di;			// 方向
}ElemType;

typedef struct {
	ElemType *base;
	ElemType *top;
	int size;
}STACK;


STACK *InitStack();
void DestoryStack(STACK *s);
int Push(STACK *s, ElemType *e);
int Pop(STACK *s, ElemType *e);
int IsEmpty(STACK *s);

// 應用一:數制轉化
// int main()
// {
// 	int num = 1348, temp;
// 	STACK *stack = InitStack();
// 	
// 	while (num){
// 		temp = num % 8;
// 		Push(stack,&temp);
// 		num /= 8;
// 	}
// 
// 	while (!IsEmpty(stack)){
// 		Pop(stack,&temp);
// 		printf("%d",temp);
// 	}
// 	
// 	DestoryStack(stack);
// 	return 0;
// }


static const POS inpos = {1,1}, outpos = {8,8};       // 起點爲(1,1)    重點爲(8,8)

int item[10][10] = {                      // 構造迷宮,可通爲0,不通爲1
	{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}
};


POS NextPos(POS curpos, int di)
{
  POS p = curpos;
	switch (di){
	case 0:
		p.x--;
		break;
	case 1:
		p.y++;
		break;
	case 2:
		p.x++;
		break;
	case 3:
		p.y--;
		break;
	}	
	return p;
}


int Pass(POS curpos)                      // 判斷是否可通
{	
	return item[curpos.y][curpos.x] == 0 ? 1 : 0;
}


void PrintItem(POS curpos)
{
	int i, j;	
	system("cls");                          // 清屏
	
	for (i = 0; i < 10; ++i){
		for (j = 0; j < 10; ++j){
			if (curpos.y == i && curpos.x == j){
				printf("@");
				continue;						              // 不加continue; 試試
			}
			if (1 == item[i][j])
				printf("*");
			else
				printf(" ");
		}
		printf("\n");
	}
}


// 應用二:迷宮求解
int main()
{	
	STACK *s = InitStack();
	ElemType e;
	POS curpos = inpos;				              // 設定當前位置爲入口位置
	int step = 1;							              // 探索第一步
	
	PrintItem(curpos);	
	do {
		if (Pass(curpos)){			              // 可通
			e.sno = step;
			e.seat = curpos;
			e.di = 0;
			Push(s,&e);                         // 將模塊的位置壓入棧
			item[curpos.y][curpos.x] = 2;		    // 留下足跡

      if (curpos.x == outpos.x && curpos.y == outpos.y){		// 如果已經是出口
				printf("OK!\n");
				break;
			}

			PrintItem(curpos);
			getch();                            // 暫停好觀察模塊的移動

			curpos = NextPos(curpos, 0);			  // 下一位置是 左邊
			step++;
		}
		else
		{
			Pop(s,&e);
			while (4 == e.di && (!IsEmpty(s))){
				item[curpos.y][curpos.x] = 3;	    // 留下足跡
				Pop(s,&e);						            // 退回一步
			}
      if (e.di < 4){						          // 換下一方向
				e.di++;
				Push(s,&e);
				curpos = NextPos(e.seat,e.di);	  // 設當前位置是新方向上的相鄰塊
			}
		}
	} while (!IsEmpty(s));
	return 0;
}


STACK *InitStack()
{
	STACK *s = (STACK *)malloc(sizeof(STACK));
	if (NULL == s)
		exit(0);

	s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
	if (NULL == s->base)
		exit(0);

	s->top = s->base;
	s->size = STACK_INIT_SIZE;

	return s;
}


void DestoryStack(STACK *s)
{
	free(s->base);
	free(s);
}


int Push(STACK *s, ElemType *e)
{
	if (NULL == s || NULL == e)
		return 0;

	if (s->size == s->top - s->base){
		s->base = (ElemType *)realloc(s->base, (s->size + STACK_INCREMENT) * sizeof(ElemType));
		if (NULL == s->base)
			return 0;
		s->top = s->base + s->size;
		s->size += STACK_INCREMENT;
	}
	
// 	*s->top = *e;
// 	s->top++;
	*s->top++ = *e;

	return 1;
}


int Pop(STACK *s, ElemType *e)
{
	if (NULL == s || NULL == e)
		return 0;

	if (IsEmpty(s))
		return 0;

// 	s->top--;
// 	*e = *s->top;
	*e = *--s->top;

	return 1;
}


int IsEmpty(STACK *s)
{
	return s->top == s->base ? 1 : 0;
}


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