数据结构迷宫问题(链式栈)

链式栈结构的实现

思路:

使用链式栈存储可通过的路径;

若当前结点已经走过上下左右四个方向仍不可通行,则把这个点弹出;

具体迷宫实现是课本的函数例子。
在这里插入图片描述

在这里插入图片描述

代码部分

#include<string>
#include<iostream>

using namespace std;

#define OK 1
#define ERROR 0
typedef int SElemType;
typedef int Status;

typedef struct//迷宫
{
	int x;
	int y;
}PosType;

typedef struct {//使用结构体存储栈中元素
	int ord;//通道块在路径中的序号
	PosType seat;//通道块在迷宫中的“坐标位置”
	int di;//从此通道块走向下一通道块的“方向”
}MazeNode;

typedef struct SNode {//链式存储栈结点
	MazeNode data;
	struct SNode* next;
}StackNode;

typedef struct LStack//链式栈结构
{
	StackNode *top;
	StackNode *bottom;//定义栈底,却不对栈底进行操作
	int size;
}LinkStack;

int Maze[10][10] = {  //定义迷宫
{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,0,0,1},
{1,0,0,0,0,1,1,0,1,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}
};

LinkStack InitStack(LinkStack s)//栈初始化
{
	s.top = s.bottom = NULL;
	s.size = 0;
	return s;
}

int StackEmpty(LinkStack s)//判断栈是否为空
{
	if (s.top == NULL && s.bottom == NULL)
	{
		return ERROR;
	}
	else
	{
		return OK;
	}
}

LinkStack push(LinkStack s, MazeNode x)//进栈操作
{
	StackNode *t = (StackNode *)malloc(sizeof(StackNode));
	if (t == NULL)
		return s;
	if (StackEmpty(s) == ERROR)
	{
		s.top = s.bottom = t;
		t->next = NULL;
		s.top->data = x;
		printf("(%d,%d)\n", s.top->data.seat.x, s.top->data.seat.y);
		s.size++;
		printf("%d\n", s.size);
		return s;
	}
	else
	{
		t->next = s.top;//续上原来的栈顶
		s.top = t;
		s.top->data = x;
		s.size++;
		return s;

	}
}

LinkStack pop(LinkStack s)//出栈操作
{
	StackNode *t;
	MazeNode q;
	if (StackEmpty(s) == ERROR)
	{
		printf("栈为空,无法进行出栈操作\n");
		return s;
	}
	if (s.top == s.bottom)//出栈元素为栈底元素
	{
		q = s.top->data;
		printf("出栈元素为(%d,%d)\n", q.seat.x, q.seat.y);
		free(s.top);
		s.top = s.bottom = NULL;
		s.size--;
		return s;
	}
	else
	{
		q = s.top->data;
		printf("出栈元素为(%d,%d)\n", q.seat.x, q.seat.y);
		t = s.top->next;
		free(s.top);
		s.top = t;
		s.size--;
		return s;
	}
}

void PrintAll(LinkStack s)//输出所有栈中元素
{
	if (StackEmpty(s) == ERROR)
	{
		printf("此栈为空栈!\n");
	}
	printf("栈中元素为:");
	while (s.top != NULL)
	{
		printf("(%d,%d)\n", s.top->data.seat.x, s.top->data.seat.y);
		s.top = s.top->next;
	}
}

LinkStack DeleteStack(LinkStack s)//销毁栈
{
	StackNode *t;
	while (s.top != NULL)
	{
		t = s.top->next;
		free(s.top);
		s.top = t;
	}
	return s;
}



bool pass(PosType postion)//判断是否可以通过
{
	if (Maze[postion.x][postion.y] == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

PosType NextPos(PosType now, int dirction)//转向函数
{
	PosType next;
	switch (dirction)
	{
	case 1:
	{
		next.x = now.x;
		next.y = now.y + 1;
		printf("向右走~\n");
		break;
	}
	case 2:
	{
		next.x = now.x + 1;
		next.y = now.y;
		printf("向下走~\n");
		break;
	}
	case 3:
	{
		next.x = now.x;
		next.y = now.y - 1;
		printf("向左走~\n");
		break;
	}
	case 4:
	{
		next.x = now.x - 1;
		next.y = now.y;
		printf("向上走~\n");
		break;
	}
	default:
		break;
	}
	return next;
}

void footprint(PosType p,int step)
{
	Maze[p.x][p.y] =4;//走过且走通的点标记为4
	printf("走过~");
}

void Markprint(PosType p)
{
	Maze[p.x][p.y] = -1;//走过且走不通的点退栈,标记为0
}


int main()
{
	printf("输出预设迷宫矩阵:\n");
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			if (Maze[i][j] == 0)
			{
				printf("O\t");//走通路径
			}
			else
			{
				printf("#\t");//墙壁
			}
		}
		printf("\n");
	}
	LinkStack path;
	path.size = 0;
	path = InitStack(path);//栈初始化
	PosType curpose;
	curpose.x = 1;
	curpose.y = 1;
	int curstep = 1;//步数
	do
	{
		if (pass(curpose))//模仿课本程序
		{
			footprint(curpose,curstep);
			MazeNode e;
			e.di = 1;
			e.ord = curstep;
			e.seat.x = curpose.x;
			e.seat.y = curpose.y;
			path = push(path, e);
			if (curpose.x == 8 && curpose.y == 8)break;
			curpose = NextPos(curpose,e.di);
			curstep++;
		}
		else
		{                                 //这里课本错误,不应该直接pop,因为这时候curpose根本没有入栈
			if (StackEmpty(path) == OK)
			{
				MazeNode e=path.top->data;
				while (StackEmpty(path) == OK && path.top->data.di == 4)
				{
					path = pop(path);
					Markprint(path.top->data.seat);
					printf("栈顶元素为:(%d,%d)", path.top->data.seat.x, path.top->data.seat.y);
					curstep--;
					//break;
				}
				footprint(path.top->data.seat, curstep);
				if (path.top->data.di < 4)
				{
					curpose = NextPos(path.top->data.seat, path.top->data.di + 1);
					path.top->data.di++;
					curstep++;
					path=push(path, path.top->data);
				}
			}
		}

	} while (StackEmpty(path) == OK);
	printf("\n");
	printf("输出迷宫可走通路径:\n");
	for (int i = 0; i < 10; i++)               //输出迷宫结果
	{
		for (int j = 0; j < 10; j++)
		{
			if (Maze[i][j] == 4)
			{
				printf("√\t");//走通路径
			}
			else if (Maze[i][j] == -1)
			{
				printf("×\t");//未走通路径
			}
			else
			{
				printf("#\t");//墙壁
			}
		}
		printf("\n");
	}
	system("PAUSE");
	return 0;
}

运行结果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

问题与反思

定义栈结构时,由于data又是一个mazenode栈,可以说栈又嵌套了栈,为函数外部的赋值造成了困难。以后要尽量避免。如果需要栈嵌套,函数最好使用指针传参,否则函数内部的值传不出去。

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
机器学习是一种人工智能(AI)的子领域,致力于研究如何利用数据和算法让计算机系统具备学习能力,从而能够自动地完成特定任务或者改进自身性能。机器学习的核心思想是让计算机系统通过学习数据中的模式和规律来实现目标,而不需要显式地编程。 机器学习应用非常广泛,包括但不限于以下领域: 图像识别和计算机视觉: 机器学习在图像识别、目标检测、人脸识别、图像分割等方面有着广泛的应用。例如,通过深度学习技术,可以训练神经网络来识别图像中的对象、人脸或者场景,用于智能监控、自动驾驶、医学影像分析等领域。 自然语言处理: 机器学习在自然语言处理领域有着重要的应用,包括文本分类、情感分析、机器翻译、语音识别等。例如,通过深度学习模型,可以训练神经网络来理解和生成自然语言,用于智能客服、智能助手、机器翻译等场景。 推荐系统: 推荐系统利用机器学习算法分析用户的行为和偏好,为用户推荐个性化的产品或服务。例如,电商网站可以利用机器学习算法分析用户的购买历史和浏览行为,向用户推荐感兴趣的商品。 预测和预测分析: 机器学习可以用于预测未来事件的发生概率或者趋势。例如,金融领域可以利用机器学习算法进行股票价格预测、信用评分、欺诈检测等。 医疗诊断和生物信息学: 机器学习在医疗诊断、药物研发、基因组学等领域有着重要的应用。例如,可以利用机器学习算法分析医学影像数据进行疾病诊断,或者利用机器学习算法分析基因数据进行疾病风险预测。 智能交通和物联网: 机器学习可以应用于智能交通系统、智能城市管理和物联网等领域。例如,可以利用机器学习算法分析交通数据优化交通流量,或者利用机器学习算法分析传感器数据监测设备状态。 以上仅是机器学习应用的一部分,随着机器学习技术的不断发展和应用场景的不断拓展,机器学习在各个领域都有着重要的应用价值,并且正在改变我们的生活和工方式。
### 回答1: 要创建一个景点导航项目,可以使用C编程语言来实现。在项目中,首先需要创建一个图的数据结构来表示景点及其之间的连接关系。 图是由一组顶点和一组边组成的数据结构。在这个项目中,每个景点可以看一个顶点,而两个景点之间的路径可以看是一条边。每个顶点可以用一个结构体来表示,其中包括景点的名称、描述和其他相关信息。 使用C语言,可以通过定义一个顶点的结构体来表示每个景点,例如: ``` struct Vertex { char name[100]; char description[200]; // 其他相关信息 }; ``` 接下来,需要创建一个图的结构体来存储所有的景点及其之间的连接关系。可以使用邻接表或邻接矩阵来表示图。在这个项目中,可以选择邻接表来实现,因为它更适合表示稀疏图(景点之间的连接关系相对较少)。 可以通过定义一个链表来表示邻接表,链表的每个节点包含一个指向顶点的指针和一个指向下一个节点的指针。邻接表可以定义为如下的结构体: ``` struct AdjacencyListNode { struct Vertex* vertex; struct AdjacencyListNode* next; }; struct Graph { int numVertices; struct AdjacencyListNode** adjacencyList; }; ``` 在图结构体中,可以使用一个数组来存储邻接表的头节点,数组的大小可以根据项目中的景点数量进行设定。对于每个顶点,可以使用一个指针数组来存储与其相连的其他顶点。 在C编程项目中,可以通过读取景点和路径信息的输入文件,并根据这些信息构建图。可以使用适当的算法(如深度优先搜索或广度优先搜索)来实现景点导航的功能,即找到两个景点之间的最短路径或导航过程。 总之,使用C编程语言可以创建一个数据结构来表示景点及其连接关系,并在此基础上实现景点导航项目。通过定义顶点和边的结构体,以及使用邻接表来表示图的邻接关系,可以实现景点导航的功能。 ### 回答2: 做一个景点导航项目需要创建一个图来表示景点之间的关系和路径。图是由顶点和边组成的数据结构,顶点代表景点,边代表景点之间的连接关系或路径。我们可以使用邻接矩阵或邻接表来表示图。 首先,我们需要定义景点的数据结构。每个景点可以包含名称、位置坐标和描述等信息。我们可以创建一个景点类来保存这些信息。接下来,我们可以创建一个列表或数组来保存所有的景点对象。 然后,我们可以使用邻接矩阵或邻接表来表示景点之间的连接关系。邻接矩阵是一个二维数组,数组的行和列代表各个景点,矩阵中的值表示两个景点之间是否有连接。邻接表是一个链表数组,每个链表中存储连接到当前景点的其他景点。 在创建图之后,我们可以实现一些功能,比如添加景点、删除景点、添加路径、删除路径等操。我们可以编写相应的方法来实现这些功能。 最后,我们可以实现景点导航的功能。比如,提供起点和终点,通过遍历图找到从起点到终点的最短路径,并显示在地图上。我们可以使用广度优先搜索或迪杰斯特拉算法来实现最短路径的查找。 总之,做一个景点导航项目需要创建一个图来表示景点之间的关系和路径。通过定义景点类、使用邻接矩阵或邻接表来表示连接关系、实现添加和删除操以及使用最短路径算法,我们可以完成一个功能完备的景点导航项目。 ### 回答3: 景点导航项目是一个基于编程的项目,旨在通过创建一个图来实现景点导航功能。该图可以是一个有向图或无向图,其中节点表示景点,边表示景点之间的连接关系。 首先,我们需要定义景点的属性。每个景点应该具有名称、位置、介绍等基本信息,这些信息可以通过一个景点类来表示。 接下来,我们可以利用图的数据结构来创建景点之间的连接关系。可以使用邻接矩阵或邻接表等方式来实现图的表示。通过将每个景点为图的节点,将景点之间的连接为图的边,我们可以构建一个完整的景点导航图。 在创建图的过程中,我们还需要考虑景点之间的权重或距离。这可以表示为边的权重,用于确定两个景点之间的距离或路径的优先级。 完成图的创建后,我们可以实现一些基本的导航功能,例如查找两个景点之间的最短路径、查找一个景点的邻接景点等。这些功能可以通过图的遍历算法(如广度优先搜索或迪杰斯特拉算法)来实现。 最后,我们可以通过用户界面(如命令行界面或图形界面)来与用户进行交互,接收用户的输入并提供相应的景点导航功能。 总之,一个景点导航项目需要通过创建一个图来表示景点之间的连接关系,并利用图的遍历和算法来实现导航功能。此项目可以通过编程语言(如C语言)来实现,结合图的数据结构和算法来实现各项功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值