迷宫(non-recursion)(即栈实现)

这是一个使用栈非递归实现的迷宫求解算法,通过VC++ 6.0 IDE进行测试。程序定义了顺序栈的数据结构,并实现了初始化、压栈、弹栈等操作。在迷宫中,通过穷举所有可能的路径,判断是否可通过并留下足迹。如果找到从起点到终点的路径,程序会输出路径;否则,表示不存在通路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
* @file Stack.h
* Test environmentof IDE: VC++ 6.0
* 顺序栈基本操作的实现 
*/

#ifndef _STACK_H
#define _STACK_H

#define STACK_INIT_SIZE 100 //初始分配量
#define STACK_INCREAMENT 10 //分配增量

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

//栈空
int StackEmpty(const SqStack& S)
{
	if(S.top == S.base)
		return true;
	else
		return false;
}

void InitStack(SqStack& S)
{
	S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if(NULL == S.base)
		exit(0);
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;
}

void Push(SqStack& S, SElemType& e)
{
	//栈满,增加空间
	if(S.top - S.base >= S.stacksize)
	{
		S.base = (SElemType*)realloc(S.base,
			(S.stacksize + STACK_INCREAMENT) * sizeof(SElemType));
		if(NULL == S.base)
			exit(0);//分配失败
		S.top = S.base + S.stacksize;
		S.stacksize += STACK_INCREAMENT;
	}
	*(S.top) = e;
	S.top++;
}

int Pop(SqStack& S, SElemType& e)
{
	if(!StackEmpty(S))
	{
		S.top--;
		e = *(S.top);
		return true;
	}
	else //栈空
		return false;
}

void DestroyStack(SqStack& S)
{
	free(S.base);
	S.base = NULL;
	S.top = NULL;
	S.stacksize = 0;
}

#endif

/**
* @file Maze.cpp
* Test environment of IDE: VC++ 6.0
* 迷宫的非递归实现
* 参考: 教材 P51
* 由于该方法采取的是穷举法,并且有8个方向可以尝试
* 显然, 路径长度最多接近(n^2)/2. 最短为对角线长度,即 n*根号2
* 因此时间复杂度上界为O(n^16),下届为O(n^8).
* 空间复杂度为矩阵大小,即O(n^2)
*/ 

#include <iostream>

//坐标位置
typedef struct PosType
{
	int x;
	int y;
}PosType;

//栈元素类型
typedef struct SElemType
{
	int ord; //通道块在路径上的"序号"
	PosType seat; //通道块在迷宫中的"坐标"
	int di; //通道块走向下一个通道块的"方向". 
	//"0,1,2,3,4,5,6,7"分别表示 "右,右下,下,左下,左,左上,上,右上" 八个方向
}SElemType;

#define MAXLENGTH 30//迷宫的最大行列
typedef int MazeType[MAXLENGTH][MAXLENGTH]; //迷宫矩阵

/** 本文件内的全局变量 */
static MazeType m; //迷宫矩阵
static int curstep = 1; //当前足迹,入口初值为1.

#include "stack.h" //引入栈的基本操作

/** 设置n x n迷宫矩阵 */
void SetMaze(int n);

/** 输出n x n迷宫矩阵 */
void Display(const int n);

/** 输出迷宫路径 */
void Print(SqStack& S);

/** 判断是否可通过. 可通过为1, 不可通过为0. */
bool Pass(const PosType& pos);

/** 留下足迹. 将当前通过的路径标记为curstep. */
void FootPrint(const PosType& pos);

/** 根据pos位置的di方向,求下一个位置 */
void NextPos(PosType& pos,int di);

/** 标记为不能通过的路径.(标记为0). */
void MarkPrint(const PosType& seat);

/**
* 若迷宫中存在从入口start到出口end的通道,则求得一条存放在
* 栈中(从栈底到栈顶),并返回true,否则返回false.
*/
bool MazePath(SqStack& S, const PosType& start, const PosType& end);

int main(int argc, char* argv[])
{
	int n=0;
	SqStack S;
	PosType start,end;
	
	std::cout << "请设置n x n迷宫的n值大小:";
	std::cin >> n;
	std::cout << "请设置迷宫的入口与出口位置(格式:x y).\n";
	std::cout << "入口:";
	std::cin >> start.x >> start.y;
	std::cout << "出口:";
	std::cin >> end.x >> end.y;
	
	SetMaze(n);
	Display(n);
	if(MazePath(S,start,end))
	{
		std::cout << "找到一条通路.\n\n";
		Display(n);
		Print(S);
	}
	else
		std::cout << "不存在通路.\n\n";

	DestroyStack(S);//释放占空间,以防内存泄露.
	return 0;
}

void SetMaze(const int n)
{
	std::cout 
		<< "请从左至右,从上至下依次设置迷宫" << std::endl
		<< "(用0表示不通,用1表示通.)" << std::endl;
	for(int j=0; j<n; j++)
		for(int i=0; i<n; i++)
			std::cin >> m[j][i];
}

void Display(const int n)
{
	std::cout << "\t迷宫结构\n";
	for(int j=0; j<n; j++)
		for(int i=0; i<n; i++)
		{
			std::cout << m[j][i] << " ";
			if(i == n-1)
				std::cout << std::endl;
		}
		std::cout << std::endl;
}

void Print(SqStack& S)
{
	SElemType e;
	while(!StackEmpty(S))
	{
		Pop(S, e);
		std::cout << e.seat.x << "," << e.seat.y << std::endl;
	}
}

bool MazePath(SqStack& S, const PosType& start, const PosType& end)
{
	PosType curpos;
	SElemType e;
	InitStack(S);
	curpos = start;
	do{
		if(Pass(curpos))
		{//当前位置可以通过
			FootPrint(curpos); //留下足迹
			e.ord = curstep;
			e.seat = curpos;
			e.di = 0; //右方向
			Push(S,e);//加入路径,保存信息.
			curstep++; 
			if(curpos.x == end.x && curpos.y == end.y)
				return true; //到达终点
			NextPos(curpos, e.di); //选择下一个位置,是当前位置的右邻.
		}
		else
		{//当前位置不可通过
			if(!StackEmpty(S))
			{
				Pop(S, e);//回溯
				curstep--;
				while(e.di == 7 && !StackEmpty(S))
				{//将不能通过的做标记
					MarkPrint(e.seat);
					Pop(S,e);//回溯
					curstep--;
				}
				if(e.di < 7)
				{//更换下一个方向进行
					e.di++;
					Push(S,e);//加入路径
					curstep++;
					curpos = e.seat;
					NextPos(curpos, e.di);//设置当前路径为下一个di方向的通道块.
				}
			}
		}
	}while(!StackEmpty(S));
	return false;
}

bool Pass(const PosType& pos)
{
	if(m[pos.x][pos.y] == 1)
		return true;
	else
		return false;
}

void FootPrint(const PosType& pos)
{
	m[pos.x][pos.y] = curstep;
}

void NextPos(PosType& pos,int di)
{//分别为"右,右下,下,左下,左,左上,上,右上"方向的增量
	PosType direc[8] = {{0,1},{1,1},{1,0},{1,-1},
	{0,-1},{-1,-1},{-1,0},{-1,1}}; 
	pos.x += direc[di].x;
	pos.y += direc[di].y;
}

void MarkPrint(const PosType& seat)
{
	m[seat.x][seat.y] = 0;
}


<think>好的,我现在需要解决Git推送被拒绝的问题,具体错误是“non-fast-forward”。首先,我得弄清楚这个错误的原因。根据我之前学过的知识,Git在推送时会检查远程分支的历史是否和本地一致。如果远程分支有其他人推送的提交,而本地没有这些提交,直接推送就会导致非快进的问题,因为本地历史与远程分叉了。 接下来,我应该回忆一下解决这个问题的方法。通常有两种主要方式:一种是先拉取远程的变更并合并到本地分支,解决可能的冲突后再推送;另一种是使用强制推送,但这会覆盖远程的历史,需要谨慎使用,特别是在团队协作中。 用户提供的引用里有没有相关的信息呢?引用[1]提到了切换分支和保留文件,似乎不相关。引用[2]是关于凭证缓存的,可能和认证有关,但和non-fast-forward无关。引用[3]是关于处理依赖的,也不相关。所以可能需要依赖通用的Git知识。 现在我需要一步步说明解决方法。首先,建议用户使用git pull来获取远程的最新提交,并合并到本地。这里需要注意的是,如果本地有未提交的更改,可能需要先暂存或提交,否则pull可能会失败。合并后解决冲突,再推送。 另外,如果用户确定自己的提交是正确的,而远程的历史需要被覆盖,可以使用git push --force,但必须小心,因为这会覆盖其他人的提交。更安全的是使用--force-with-lease,它会在强制推送前检查远程分支是否和本地预期的一致,避免覆盖他人提交。 还需要提醒用户,强制推送在团队协作中的风险,建议在个人分支或确定没有冲突的情况下使用。此外,如果分支是被保护的,可能需要权限才能强制推送。 最后,生成相关问题,比如如何避免这种问题,或者如何撤销强制推送,以及合并和变基的区别等。</think>### 解决Git推送被拒绝的问题(非快进更新) 当Git提示`rejected non-fast-forward`错误时,通常是因为远程仓库包含本地没有的新提交,导致推送路径分叉。以下是解决步骤: --- #### **1. 拉取远程变更并合并** **步骤:** - 使用`git pull`拉取远程分支的最新提交,并自动与本地分支合并: ```bash git pull origin <分支名> ``` 若存在冲突,需手动解决后提交合并结果: ```bash git add . git commit -m "合并远程分支" git push origin <分支名> ``` --- #### **2. 使用变基(Rebase)整合提交** 若希望本地提交历史更线性,可在拉取时用`--rebase`: ```bash git pull --rebase origin <分支名> ``` 解决冲突后继续变基: ```bash git rebase --continue ``` 最后推送: ```bash git push origin <分支名> ``` --- #### **3. 强制推送(慎用!)** **适用场景**:确定远程历史需要被覆盖(如个人分支、临时修复)。 - 强制推送本地提交,覆盖远程分支: ```bash git push --force origin <分支名> ``` 更安全的选项(检查远程状态): ```bash git push --force-with-lease origin <分支名> ``` **风险提示**:强制推送会覆盖他人提交,可能导致协作混乱[^1]。 --- #### **4. 检查分支保护规则** 若远程分支设置了保护(如GitHub的Protected Branches),需确保有权限推送或联系管理员调整规则。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值