数据结构第三章设计作业(栈实现迷宫求解)

#define _CRT_SECURE_NO_WARINGS
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<iomanip>
#define STACK_INIT_SIZE 1000
using namespace std;

int mazeMap[10][10] =
{
		{0,0,0,0,0,0,0,0,0,0},
		{0,1,0,1,1,1,1,0,1,0},
		{0,0,0,1,1,1,1,0,1,0},
		{0,1,0,1,0,0,0,1,1,0},
		{0,1,0,1,0,1,0,1,1,0},
		{0,1,1,1,0,1,1,1,1,0},
		{0,1,0,1,1,1,0,1,1,0},
		{0,1,0,1,0,1,0,0,1,0},
		{0,0,1,1,1,1,1,1,1,0},
		{0,0,0,0,0,0,0,0,0,0}

};
typedef struct
{
	int row;
	int col;
}posType;

typedef struct
{
	int num;//通道块在路径上的序号
	posType coordinate;//通道块在迷宫里的坐标
	int dir;//从此通道块走向下一通道块的方向
}SElemType;

typedef struct
{
	SElemType* base;
	SElemType* top;
	int stackSize;
}sqStack;


void PrintMaze()
{
	cout << "the map of maze" << endl;
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			cout << setw(3) << mazeMap[i][j];
		}
		cout << endl;
	}
}

void initStack(sqStack& s)
{
	s.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	s.top = s.base;
	s.stackSize = STACK_INIT_SIZE;
}

void push(sqStack& s, SElemType& e)
{
	*s.top = e;
	s.top++;
}

void pop(sqStack& s, SElemType& e)
{
	if (s.top == s.base)
	{
		return;
	}
	else
	{
		s.top--;
		e = *(s.top);
	}
}

bool isEmpty(sqStack s)
{
	if (s.base == s.top)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void markPrint(posType pos)//留下不能通过的标记
{
	cout << "(" << pos.row << "," << pos.col << ") was blocked!" << endl;
	mazeMap[pos.row][pos.col] = 0;
}

void makeFootPrint(posType curPose, int curStep)
{
	if (curPose.row == 1 && curPose.col == 1)
	{
		mazeMap[curPose.row][curPose.col] = 0;
	}
	else
	{
		mazeMap[curPose.row][curPose.col] = curStep;
	}
}



bool havePass(posType curPose)//判断当前位置是0还是1
{
	if (mazeMap[curPose.row][curPose.col] == 1)
	{
		return true;
	}
	else
	{
		return false;
	}
}

posType tryNextPos(posType curPos, int i)
{
	switch (i)
	{
	case 1:
		curPos.row++;//下
		break;
	case 2:
		curPos.col++;//右
		break;
	case 3:
		curPos.row--;//上
		break;
	case 4:
		curPos.col--;//左
		break;
	}
	return curPos;
}
/*对于第一个格子,先push,(第一个格子元素一定是1,一定走得通)然后通过对第一个格子push pop来确定第一个格子的dir(确定的过程是将(sElemType类型的)e入栈出栈)
 *然后默认往下尝试,如果第一个格子往下是1(第一个格子就真正成功入栈了),说明尝试成功。对于每个格子,他想入栈不但自己要是1,而且他周围要有路可走他才能真正入栈
 *但假如第一个格子往下尝试不成功,第一个格子就被pop出来修改dir,然后再push进去用havepass判断尝试是否成功
 */
int mazePath(posType start, posType end)
{
	sqStack s;
	posType curPos;
	SElemType e;
	int curStep;
	initStack(s);
	curPos = start;//把当前位置设为start
	curStep = 1;//当前步数为1
	cout << "begin:" << "(" << start.row << "," << start.col << ")" << endl;
	do
	{
		if (havePass(curPos))//如果当前位置走得通(当前位置是1)
		{
			makeFootPrint(curPos, curStep);
			cout<<"Step"<<curStep<<":"<<"(" << curPos.row << "," << curPos.col << ")" << endl;
			e.num = curStep;
			e.dir = 1;//默认是先往下尝试
			e.coordinate = curPos;
			push(s, e);//第一二三。。。个格子入栈
			if (curPos.row == end.row && curPos.col == end.col)//是否到终点
			{
				cout << "Finished!" << endl;
				return 1;
			}
			curPos = tryNextPos(curPos, 1);//刚刚进栈的这个格子尝试(默认)往下走
			curStep++;//直接+1
			//cout << "step" << curStep<<":";
		}
		else
		{
			if (!isEmpty(s))
			{
				pop(s, e);//一进else就被pop出来,如果e的dir==4,那栈就会连pop两个(因为直接进while)。e在这里更新为不合规的节点,在while里变成不合规节点的前一个节点
				while (!isEmpty(s) && e.dir == 4)//某一个格子四个方向都没有路走
				{
					markPrint(e.coordinate);//就对这个格子做一个标记(把它也改成0)
					pop(s, e);//e是这个被pop出来的元素, 某个格子向四周尝试,该格子不断的被push,pop,   直到尝试到一个确定的方向,才会把该方向的新格子push进栈
					curStep--;//curStep是push一个元素开始尝试它的第一个dir的时候已经+1了,当尝试了四个方向都不行才减1
					cout << "Back to:" << "(" << e.coordinate.row << "," << e.coordinate.col << ")" << endl;
				}
				if (e.dir < 4)//pop出来修改e.dir,再push进去
				{
					e.dir++;
					push(s, e);
					curPos = tryNextPos(e.coordinate, e.dir);//当前位置只能在这修改
				}
			}
		}
	} while (!isEmpty(s));
	cout << "No path found!" << endl;
	return 0;
}


int main()
{
	PrintMaze();
	posType start, end;
	start.row = 1;
	start.col = 1;
	end.row = 8;
	end.col = 8;
	if (mazePath(start, end))
	{
		mazeMap[1][1] = 1;
		PrintMaze();
	}
	return 0;
}

航班订票系统:航空客运订票的业务活动包括查询航线、客票预定和办理退票等,设计航班信息、订票系统的存储结构,完成下面基本要求 基本要求 (1) 每条航线所涉及的信息有:终点站名、航班号、飞机号、飞行日期(具体时间)、成员定额、余票量、已订票的客户名单(包括姓名、订票量、舱位等级1,2或3)以及等候替补的客户名单(包括姓名、所需票量) (2) 要求数据等存放在文件中 (3) 录入:可以录入航班情况(数据可以存储在一个数据文件中,数据结构、具体数据自定) (4) 查询:可以查询某个航线的情况(如,输入航班号,查询起降时间,起飞抵达城市,航班票价,票价折扣,确定航班是否满仓); (5) 可以输入起飞抵达城市,查询飞机航班情况; (6) 订票:(订票情况可以存在一个数据文件中,结构自己设定),可以订票,如果该航班已经无票,可以提供相关可选择航班;若已满员或余票额少于订票额,则需重新询问客户要求。若需要,可登记排队候补; (7) 退票:可退票,退票后修改相关数据文件;然后查询该航班是否有人排队候补,首先询问排在第一的客户,若所退票额能满足他的要求,则为它办理订票手续,否则依次询问其他排队候补的客户 (8) 修改航班信息:当航班信息改变可以修改航班数据文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值