记录自己的学习数据结构(C语言版-严蔚敏)的历程
按照书上写的补全,望指教
1.常量声明
constant.h
#define TRUE 1
#define FALSE 2
#define OK 3
#define ERROR 4
#define INFEASIBLE 5
#define OVERFLOW 6
2.栈的基本操作(Get略改动)
Stack.h
#include "constant.h"
#include <stdlib.h>
#define MAXSIZE 100
typedef struct
{
int x;
int y;
}PosType;
typedef struct
{
int ord;
PosType seat;
int di;
}Box;
typedef int Status;
typedef Box ElemType;
// 结构体定义,base为栈底指针,base为NULL时表示栈不存在,top为栈顶指针,指向栈顶元素的下一个位置!!!
//top == base 表示空栈
typedef struct
{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;
// 顺序栈的初始化
Status InitStack(SqStack &S)
{
S.top = S.base = new ElemType[MAXSIZE];
if(!S.base) exit(ERROR);
S.stacksize = MAXSIZE;
return OK;
}
// 顺序栈的入栈
// S是一个顺序栈,e是要入栈的元素
Status Push(SqStack &S, ElemType e)
{
//如果栈满,返回ERROR
if(S.top-S.base == S.stacksize) exit(ERROR);
//后置加,即*S.top=e; S.top++;
*S.top++ = e;
return OK;
}
// 顺序栈的出栈
// S是一个顺序栈,出栈元素用e带回
Status Pop(SqStack &S, ElemType &e)
{
//如果栈空,返回ERROR
if(S.top == S.base) exit(ERROR);
//前置减,即e=*S.top; S.top--;
e = *--S.top;
return OK;
}
// 取栈顶元素
// S是一个顺序栈,栈顶元素用e带回
ElemType Get(SqStack &S, ElemType &e)
{
//如果栈空,返回ERROR
if(S.top == S.base) exit(ERROR);
//区别于出栈,只是取栈顶元素所以top不能变,但top是指向栈顶元素的下一个位置!所以用*(S.top - 1)表示栈顶元素
e = *(S.top - 1);
return e ;
}
main.cpp主要实现
用二维数组创建地图,0代表可以通过,1代表不能通过。
#include <iostream>
#include "Stack.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
//函数申明
Status Pass(PosType now); //判断当前块是否能通过
void FootPrint(PosType now);//留下已走过标记
void MarkPrint(PosType now);//留下不可通过标记
PosType NextPos(PosType now,int di);//到下一位置
Status MazePath(PosType start, PosType end);//寻找一条可能路径
//初始化地图(可自行修改,方便测试)
int maze[6][6] ={ {0,1,0,0,0,1},
{1,1,0,1,0,0},
{0,0,1,1,1,0},
{1,0,0,0,0,1},
{1,1,1,1,1,1},
{1,0,0,0,0,0}
};
int main(int argc, char** argv) {
//定义入口和出口,结构体声明见Stack.h
PosType start, end;
start.x = 0; start.y = 0;
end.x = 5; end.y = 5;
//找路径,有就输出,没有输出语句提示
MazePath(start,end);
return 0;
}
Status MazePath(PosType start, PosType end)
{
SqStack S;
InitStack(S);
//curpos是当前位置,初值是start
PosType curpos = start;
//curstep记录步数,入口算一步(我脑子不好使)
int curstep = 1;
Box e;
do
{
//如果curpos可以通过
if(Pass(curpos) == OK)
{
//留下已通过标记
FootPrint(curpos);
//用e记录当前路径元素
e.ord = curstep;
e.seat = curpos;
e.di = 1;
//将e入栈S
Push(S,e);
//如果到达终点
if(curpos.x == end.x && curpos.y == end.y)
{
printf("可以找到一条可能路径\n");
while(S.base!=S.top)
{
//这里可以通过判断di来输出方向,根据curstep输出步数,略去
printf("(%d,%d)\t",S.base->seat.x,S.base->seat.y);
S.base++;
}
return 0;
}
curpos = NextPos(curpos,1);
curstep++;
}
//如果不能通过
else
{
//如果栈不空
if(S.base != S.top)
{
//e出栈S
Pop(S,e);
//当4个方向都探索完,且栈不空
while((e.di == 4) && (S.base != S.top))
{
//留下不可通过标记
MarkPrint(curpos);
//e出栈S
Pop(S,e);
//很坑的点,在上一个语句出栈后可能为空栈,
//取不到栈顶元素(空栈)时也应该判定为不能找到路。
if(S.base != S.top)
{
//取栈顶元素
curpos = Get(S,e).seat;
}
else
{
printf("找不到一条可能路径\n");
return 0;
}
}
//如果还有其他方向未探索
if(e.di < 4)
{
//记录探索方向
e.di++;
//e入栈S
Push(S,e);
curpos = NextPos(curpos,e.di);
}
}
}
}while(S.base != S.top);//栈不空,继续寻找
printf("找不到一条可能路径\n");
return 0;
}
void FootPrint(PosType now)
{
maze[now.x][now.y] = 1;
}
PosType NextPos(PosType now,int di)
{
switch(di)
{
case 1:
{
now.y++;
break;
}
case 2:
{
//1方向不通,但是curpos.y在1时++了,所以先得--退回上一个路径,下面同理
now.y--;
now.x++;
break;
}
case 3:
{
now.x--;
now.y--;
break;
}
case 4:
{
now.y++;
now.x--;
break;
}
}
return now;
}
Status Pass(PosType now)
{
//对应点可通且不越界
if(maze[now.x][now.y] == 0 && now.x >= 0 && now.x < 6 && now.y >= 0 && now.y < 6)
return OK;
else
return ERROR;
}
void MarkPrint(PosType now)
{
maze[now.x][now.y] = 1;
}