基于栈的应用--列车车厢重排问题、开关盒布线问题、离线等价类问题、迷宫老鼠(深度优先、回溯)问题的算法实现

本文介绍了四个基于栈和深度优先搜索、回溯算法的问题:列车车厢重排问题,开关盒布线问题,离线等价类问题以及迷宫老鼠问题。通过具体的代码实现,阐述了如何运用这些算法解决实际问题,如车厢有序调度、无交叉布线、等价类划分和寻找迷宫路径。
摘要由CSDN通过智能技术生成

文章所用的栈stackArray见栈的数组实现

列车车厢重排问题

一列货运列车有n节车厢,将原来的乱序列车车厢如[581742963]通过输入轨道后,在中转站中经过中转调度,将其有序地驶出输出轨道,如[987654321]。中转站有一个输入轨道,一个输出轨道和k个缓冲轨道。对缓冲轨道的要求为:缓冲轨道上面的车厢序号小于下面的车厢序号,即序号顶部往下为递增的;编号为u的车厢应该进入的缓冲轨道,其顶部车厢编号是大于u的最小者。
代码实现为:

//=========================列车车厢重排=================================
//分析可得 时间复杂度为O(numberOfCarriages*numberOfTracks)
//算法主要步数集中在对numberOfCarriages-1节车厢在while或者else的条件下再次遍历numberOfTracks条轨道
namespace carriageRearrange {
   
	//列车车厢重排需要用到的全局变量
	stackArray<int>* tracks;	//缓冲轨道数组
	int numberOfCarriages;	//输入列车序列的车厢数量
	int numberOfTracks;		//用于缓冲排序的轨道数量
	int smallestCarriage;	//在缓冲轨道中最小的车厢
	int itsTrack;			//最小车厢对应的缓冲轨道
	
	void outputFromHoldingTrack();
	bool putIntoHoldingTrack(int);

	//函数railrod 遍历输入车厢序列,进行排序
	bool railroad(int inputOrder[],int _numberOfCarriages,int _numberOfTracks) {
   
		numberOfCarriages = _numberOfCarriages;
		numberOfTracks = _numberOfTracks;
		tracks = new stackArray<int> [numberOfTracks+1];
		int nextCarriageToOutput = 1;//下一出轨道的车厢序号
		smallestCarriage = numberOfCarriages + 1;//初始时无车厢在缓冲轨道中

		for (int i = 0; i < numberOfCarriages;++i) {
   //遍历输入车厢序列
			if (inputOrder[i] == nextCarriageToOutput) {
   //当前车厢可以移动到出轨道
				cout << "Move carriage[" << inputOrder[i] << "] from input track "
					<<"to output track" << endl;
				++nextCarriageToOutput;

				//将缓冲轨道中可以移出的车厢进行移动
				while (smallestCarriage==nextCarriageToOutput) {
   
					outputFromHoldingTrack();
					++nextCarriageToOutput;
				}
			}
			else {
   //当前车厢不能移动到出轨道 将其移动到一个缓冲轨道
				if (!putIntoHoldingTrack(inputOrder[i])) {
   
					cout << "Rearranged failed!" << endl;
					return false;
				}
			}
		}
		delete[] tracks;
		return true;
	}

	void outputFromHoldingTrack() {
   
		try {
   
			tracks[itsTrack].pop();//当前缓冲轨道最小车厢出栈 移出到出轨道
		}
		catch (const stackEmpty& e)
		{
   
			e.output();
		}
		cout << "Move carriage[" << smallestCarriage << "] from holding track["
			<< itsTrack << "] to output track" << endl;

		//更新下一个缓冲轨道中编号最小的车厢和它所在的轨道编号

		//smallestCarriage = numberOfCarriages + 1;
		smallestCarriage = numberOfCarriages + 2;
		//Q:为什么+2 A:因为如果+1会在排序完成后与递增的nextCarriageToOutput相等 从而导致对下一个不存在
		//的车厢再次进行outputFromHoldingTrack() 从而导致数组越界 对一个空数组进行pop()导致异常
		//如果没有对pop()进行try-catch对stackArray中的异常进行处理 那么程序将崩溃
		for (int i = 1; i <= numberOfTracks;++i) {
   
			if ((!tracks[i].empty()) && (tracks[i].top()<smallestCarriage)) {
   
				smallestCarriage = tracks[i].top();
				itsTrack = i;
			}
		}
	}

	bool putIntoHoldingTrack(int carriage) {
   
		int bestTrack = 0;//目前最适合的缓冲轨道
		int bestTop = numberOfCarriages + 1;//bestTrack中的顶部车厢

		//遍历缓冲轨道 找到最适合的bestTrack
		for (int i = 1; i <= numberOfTracks;++i) {
   
			if (!tracks[i].empty()) {
   
				int currentTrackTop = tracks[i].top();
				if (carriage < currentTrackTop && currentTrackTop < bestTop) {
   
					bestTop = currentTrackTop;
					bestTrack = i;
				}
			}
			else {
   
				if
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值