铁路调度问题 -- 递归 -- 栈 -- 笔试题目

前言

通过这个问题的解答,思考,感觉对递归掌握更深了一点,很棒的一道题。代码有详细解释,互相学习~

铁路调度问题 – 递归 – 栈 – 笔试题目

左边停了N个车厢,N个车厢依次编号为1-N。现希望通过中间的Y字型铁轨。将所有车厢拉到右边,所有车厢不允许走重复的路。
在这里插入图片描述
请列出所有列车到右边铁路后,右边列车所有可能的排法

  • 注意并非全排列
#include <iostream>
#include <stdlib.h>
using namespace std;

/*
问题:C语言编程。Y字形铁路如下图:
	铁路调度问题
	---》  ---》
		| |
		| |
		| |
		———
	左边停了N个车厢,N个车厢依次编号为1-N。现希望通过中间的Y字型铁轨。将所有车厢拉到右边,所有车厢不允许走重复的路。
	
	请列出所有列车到右边铁路后,右边列车所有可能的排法
解析:
	1.可以将Y字型中间看作一个栈
	2.每次都有只有两种处理方式:出栈/入栈。这是一种典型的递归问题
算法:
	根据解析可以用两重递归,入栈与出栈分别为一个递归。
	条件:
-- 进栈递归跳出条件为最后一个元素进栈,本题目可以用左侧编号=0表示,因为
-- 出栈递归跳出条件为栈空
*/

// 定义一个简单的栈类
class myStack{
private:
	int top;	/* 栈顶的下标 */
	int *data;	/* 栈空间 */
	
public:
	myStack( int n ){
		/* n为栈的大小 */
		top = -1;
		data = new int[n];
	}
	~myStack(){
		delete [] data;
	}
public:
	/* 三个操作函数 省略容错处理(解本题目可省略) */
	void push(int q){
		top ++ ;
		data[top] = q;
	}
	bool isEmpty(){
		return top==-1?true:false;
	}
	int pop(){
		return data[ top -- ];
	}
};

/* 	__process递归函数声明,提供process调用,再process下面定义
参数都是记录当前处理的状态:
	mystack  ----  Y字型中间栈的状态
	pos   	-----  左侧待操作的车厢编号
	path[]  -----  记录右侧轨道状态的数组,存储编号排列
	curp	-----  记录右侧车厢数目
  */
void __process( myStack &mystack , int pos , int path[] , int curp ); 

/* process函数,输入参数为左侧待操作车厢数目 */
void process( int N ){

	myStack mystack(N);			/* 模拟Y字型中间栈 */
	int path[N];				/* 存放右侧车厢编号排列 */
	cout << "所有输出序列为:"<< endl;
	__process( mystack , N , path , 0 ); /* 第一次操作 */
}
/*__process 函数 定义*/
void __process( myStack &mystack , int pos , int path[] , int curp ){
	
	/* 每次操作都为 -- 两个选择,入栈以及出栈 */
	// 1.入栈
	if( pos > 0 ) { 		// 入栈条件,左侧有车厢,即pos>0  
		mystack.push( pos );  
		__process(mystack , pos-1 , path , curp);
							// 进行下一次抉择
		mystack.pop(); 		// 恢复原状
	}
	// 2.出栈
	if(!mystack.isEmpty()) {
		int m = mystack.pop();	//把当前车厢出栈 	
		path[curp] = m; 		// 出栈车厢放在右边
		__process(mystack , pos , path , curp + 1 ); 
								// 进行下一次抉择
		mystack.push(m); 		// 恢复原状
	}
	// 3.最终 pos == 0 左侧无车厢 && isEmpty 栈空,栈中无车厢 , 此时右侧调度完成,输出结果 
	if( pos == 0 && mystack.isEmpty() ){
		for( int i = curp-1 ; i >= 0 ; i-- ){
			// 此时curp为 N ,车厢按照从左到右输出,最左侧为path最后一个元素
			cout << path[i] << " " ;
		}
		cout << endl;
	}
}
int main(){
	int n ;
	cout << "左侧车厢数量 : " ;
	cin >> n;
	process(n);
}

测试结果

  • 在这里插入图片描述
  • 在这里插入图片描述
  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
1. 把一个链表反向,递归,非递归都写一遍。 1.试编写3个函数实现   (1)建立一个双向链表   (2)插入一个节点   (3)删除一个节点 2.自己定义数据结构,写出程序:二叉树的前序遍历。 3.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数。 4.下面哪种排序对12354最快 a quick sort b.buble sort c.merge sort 5.哪种结构,平均来讲,获取一个值最快 a. binary tree b. hash table c. stack 6.一个二叉树的三种遍历方的输出结果 7.链表按升序打印每打印完一个节点就将该节点从链表中删除 8.选择一种算法来整理出一个链接表。你为什么要选择这种方?现在用o(n)时间来做。 9. 用一种算法在一个循环的链接表里插入一个节点,但不得穿越链接表。    10.给两个变量,如何找出一个带环单链表中是什么地方出现环的? 11.哈希表和数组的定义,区别,优缺点。 12.链接表和数组之间的区别是什么? 任选一门语言,当场定义二叉排序树数据结构,写出两个函数:初始化,删除一个节点,20分钟 13. 递归的折半查找算法[不限语言] 14. 解释一下什么是B+树,如何实现B+树的查找和插入.(用图示) 15.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数。 13.排序方比较 (intel) 排序方 平均时间 最坏时间 辅助存储 直接插入排序 O(N2) O(N2) O(1) 起泡排序 O(N2) O(N2) O(1) 快速排序 O(Nlog2N) O(N2) O(Nlog2N) 简单选择排序 O(N2) O(N2) O(1) 堆排序 O(Nlog2N) O(Nlog2N) O(1) 归并排序 O(Nlog2N) O(Nlog2N) O(n) 基数排序 O(d(n+radix)) O(d(n+radix)) O(radix) 17.一个链表的操作,注意代码的健壮和安全性。要求: (1)增加一个元素; (2)获得头元素; (3)弹出头元素(获得值并删除)。 18.内排序算法 19.折半查找的复杂度,证明 20.sizeof()和strlen()的使用. 21.顺序存储结构的优点,散列的思想是什么? 22.汉罗塔算法,不能递归... 23.一个链表的结点结构 struct Node { int data ; Node *next ; }; typedef struct Node Node ; (1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel) (2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表 依然有序。 (3)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表 依然有序,这次要求用递归进行。 ( Autodesk) 24.编最优化Bubble(int *pIntArray,int L),要求:交换元素不能用临时变量,如果有序需要最优。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值