实验2用堆栈解决火车车厢重排问题的编程

合集下载

数据结构.车厢调度

数据结构.车厢调度


问题 分析:
从具体问题入手: 第一步:假如有1,2,3准备进栈,此时具体的过程如下
第二步:对上述过程的进一步分析,一个数进栈以后,有 两种处理方式:要么下一个元素进栈(如果有的话),要 么立刻出栈;一个数出栈以后,要么继续出栈(如果栈不 为空),要么下一个元素进栈(如果有的话)
第三步:继续分析,由此得出一个结论,在操作过程中的 任何状态下都有两种可能的操作:“入”和“出”。每个 状态下处理问题的方法都是相同的,这说明问题本身具有 天然的递归特性,可以考虑用递归算法实现。
1出

S(1,path,2) 停止 停止 输出 path[i]:2,1
S(1,path,1) push(2) S(2,path,1) pop()
停止
S(2,path,1) 停止
停止
输出 p①:
②:
1
③:
④:
2 1 ⑤: 1 ⑥: 1 ⑦:
⑧:
2
⑨:
本程序的主要算法分析: 调度函数的伪码算法如下: void Scheduling(int pos, int path[],int i) { if(pos<n) { 一个数进栈后,有两种处理方式:要么下一个数的进栈, 要么立刻出栈} if(!IsEmpty()==true){ 一个数出栈后,有两种处理方式:要么继续出栈,要么下一 个数的进栈} if(pos==n&&IsEmpty()){ 一种可能输出序列产生,输出} }
主函数调用Scheduling函数后后究竟怎么执行的呢 现考虑只有两个车厢1,2
S(2,path,0) 停止 S(1,path,0) push(2) S(2,path,0) pop() t=path[0]=p op() S(1,path,1) push(t) t=path[0]=p op() S(1,path,1) push(t) S(1,path,1) 停止 t=path[0]=p op() S(1,path,2) push(t)

火车车厢重排-问题解决-c++(队列方法)

火车车厢重排-问题解决-c++(队列方法)

火车车厢重排问题c++解决方法(队列实现)//Queue.h#ifndef QUEUE_H#define QUEUE_H#include<iostream>using namespace std;template<typename T>class Queue{public:virtual void MakeEmpty()=0;virtual void Enqueue(T x)=0;virtual T Dequeue()=0;virtual bool IsEmpty()const=0;virtual bool IsFull()const=0;virtual T GetFirstItem()=0;};class EmptyQueue{};class FullQueue{};#endif//LinkQueue.h //链表队列#ifndef LINKQUEUE_H#define LINKQUEUE_H#include<iostream>#include"Queue.h"using namespace std;template<typename T>struct Node{T date;Node<T> *next;};template<typename T>class LinkQueue:public Queue<T>{template<typename T>friend ostream & operator<<(ostream &s,const LinkQueue<T> &lq);public:LinkQueue();~LinkQueue();void MakeEmpty();void Enqueue(T x);T Dequeue();bool IsEmpty()const;bool IsFull()const;T GetFirstItem();T GetlastItem();private:Node<T> *front;Node<T> *rear;};template<typename T>LinkQueue<T>::LinkQueue(){front=new Node<T>;front->next=NULL;rear=front;}template<typename T>LinkQueue<T>::~LinkQueue(){MakeEmpty();delete front;}template<typename T>void LinkQueue<T>::Enqueue(T x) {Node<T> *newnode;newnode=new Node<T>;newnode->date=x;newnode->next=NULL;rear->next=newnode;rear=newnode;}template<typename T>T LinkQueue<T>::Dequeue(){if(IsEmpty())throw EmptyQueue();Node<T> *p;p=front->next;T x=p->date;front->next=p->next;if(p->next==NULL)rear=front;delete p;return x;}template<typename T>bool LinkQueue<T>::IsFull()const {return false;}template<typename T>bool LinkQueue<T>::IsEmpty()const {return front==rear;}template<typename T>T LinkQueue<T>::GetFirstItem() {if(IsEmpty())throw EmptyQueue();Node<T> *p;p=front->next;return p->date;}template<typename T>T LinkQueue<T>::GetlastItem() {if(IsEmpty())throw EmptyQueue();return rear->date;}template<typename T>void LinkQueue<T>::MakeEmpty() {Node<T> *p;while(front->next!=NULL){p=front->next;front->next=p->next;delete p;}}template <typename T>ostream & operator<<(ostream &s,const LinkQueue<T> &lq){Node<T> *p;p=lq.front->next;while(p!=NULL){s<<p->date<<" ";p=p->next;}return s;}#endif//TrainResort.h//火车车厢重排代码核心部分#ifndef TRAINRESORT#define TRAINRESORT#include<iostream>#include"LinkQueue.h"using namespace std;class TrainResort{friend ostream & operator <<(ostream &s,TrainResort &tr); public:TrainResort(LinkQueue<int> *or,int m=3);~TrainResort();private:int buf;LinkQueue<int> orbit;LinkQueue<int> *buffer;};TrainResort::TrainResort(LinkQueue<int> *or,int m){buf=m;while(!or->IsEmpty())orbit.Enqueue(or->Dequeue());buffer=new LinkQueue<int>[buf];}TrainResort::~TrainResort(){delete []buffer;}ostream & operator <<(ostream &s,TrainResort &tr){int nowOut=1;int temp;int x,y;int z;while(!tr.orbit.IsEmpty()){x=0,y=0;z=0;temp=tr.orbit.Dequeue();if(temp==nowOut){tr.buffer[0].Enqueue(nowOut);nowOut++;for(int j=1;j<tr.buf;j++){int k=0;while(!tr.buffer[j].IsEmpty()&&tr.buffer[j].GetFirstItem()==nowOu t){tr.buffer[0].Enqueue(nowOut);nowOut++;tr.buffer[j].Dequeue();k++;}if(k!=0){if(temp==nowOut){tr.buffer[0].Enqueue(nowOut);nowOut++;}j=0;}}}else{for(int j=1;j<tr.buf;j++){if(!tr.buffer[j].IsEmpty()){if(temp-tr.buffer[j].GetlastItem()>0){y=(x>temp-tr.buffer[j].GetlastItem()?y:j);x=(y==j?temp-tr.buffer[j].GetlastItem():x);}}else{z=j;}}if(y!=0){tr.buffer[y].Enqueue(temp);}else if(z!=0){tr.buffer[z].Enqueue(temp);}else{s<<"Don't resort!";break;}}}s<<tr.buffer[0];return s;}#endif(注:可编辑下载,若有不当之处,请指正,谢谢!)。

车厢调度算法实习报告

车厢调度算法实习报告

实习二报告题目:2.3车厢调度难度系数: 4选择的功能实现:利用堆栈存储结构模拟车厢调度过程一、需求分析1.本演示程序中,使用顺序堆栈作为车厢调度车站,车子按1,2…n的顺序依次排列在车站入口处,其中n<=50,堆栈中每个元素存储一个车厢号码代表该车。

用户自己输入等候车厢的数目n,回车后会出现所有可能的车厢输出情况。

如果输入小于0或n>50则会提示出错。

2.演示程序以用户和计算机对话方式执行。

即在计算机终端上显示提示信息之后,由用户在键盘上输入车厢数目n后,相应的结果会显示在屏幕上。

3.程序执行的命令包括:1)构造顺序堆栈2)初始化堆栈3)调用递归函数4. 测试数据n=1, 输出结果为:1n=2, 输出结果为:21 12n=3, 输出结果为:321 231 213 132 123n=4,输出结果为:4321 3421 3241 3214 2431 2341 2314 2143 2134 1432 1342 13241243 1234二、概要设计为实现以上功能,使用顺序堆栈结构构造了调度站模型。

1.设定栈的抽象数据类型定义:ADT Stack(数据对象:D={ai|ai∈charset,i=1,2,…,n>0}数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,…n}基本操作:Init(&s)操作结果:构造一个空栈S;isEmpty()初始条件:栈s已存在操作结果:如果栈s空,则返回1,否则返回0;Pop()初始条件:栈s已存在操作结果:删除s的栈顶元素,并以temp返回其值Push(q)初始条件:栈s已存在操作结果:在栈s的栈顶插入新的栈顶元素q}ADT Stack2.本程序包含三个模块1)主程序模块:Void main(){初始化;For(int a=0;a<100;a++){If(c==’Q’||c=’q’)Return 0;Else{接收命令;处理命令;}}}2)栈模块—实现栈抽象数据类型3)递归模块—实现算法递归调用各模块之间的调用关系如下:主程序模块递归模块栈模块三、详细设计1.构造堆栈struct snode{int data[max];int top;}s;栈的基本操作void init() //初始化{s.top=-1; }void push(int q) //入栈操作{s.top++;s.data[s.top]=q;}int pop() //出栈操作{int temp;temp=s.data[s.top];s.top--;return temp;}int isEmpty() //判读栈是否为空{if(s.top==-1)return 1;elsereturn 0;}2.递归算法:void digui(int pos,int path[],int curp){int m,i;if(pos<n)//当一个元素进入后,有两种选择,一是压栈下一个,一个是退出自己{ push(pos+1);//选择把下一个压栈digui(pos+1,path,curp);pop();//选择把下一个压栈进去的元素退出去,待会等待把自己退出去(恢复压栈前的初始状态)}if(!isEmpty())//当一个元素出去后,两种选择,一个是继续退下一个,一个是把自己再装进来{m=pop();path[curp]=m;curp++;digui(pos,path,curp);//退出去以后继续调用push(m);//恢复退出前初始的状态}if(pos==n&&isEmpty()){for(i=0;i<curp;i++)printf("%2d",path[i]);printf("\t");}}3.主函数算法int main(){cout<<"********************欢迎进入车厢调度程序********************"<<endl;char c;int path[max];for(int a=0;a<100;a++){cout<<"\n退出实验请输入Q,继续实验请输入其他任何一个字母:";cin>>c;if(c=='Q'||c=='q')return 0;else{printf("输入车厢数目:");scanf("%d",&n);if(n<=0||n>50){printf("input error!\n");}else{init();push(1);printf("输出结果:\n");digui(1,path,0);}}}return 1;}4.函数调用关系图四、调试分析1.本次作业的数据结构比较简单,但是递归算法是其核心,在每一个车厢入栈或出栈后,都面临两种选择,一个是继续入栈,一个是继续出栈,正如提示所分析的,该情况具有先天的递归性,所以本代码编写时使用了递归算法,依次求得各种情况的值。

火车车厢重排问题

火车车厢重排问题

⽕车车厢重排问题2014-11-04主要数据结构:栈题⽬:⼀列⽕车要将n节车厢分别送往n个车站按1~n的次序编号,⽕车按照n,n-1,…1的编号次序经过车站。

假设车厢的编号就是其⽬的地车站的编号。

要求:给定⼀个任意的车厢排列次序。

重新排列车厢,使其按照从1到n的次序排列。

规定重排时,只能从⼊轨到缓冲铁轨,或者从缓冲铁轨到出轨。

总的思路:⾸先:将所需要重排的车厢编号从左到右依次输⼊数组carrage中;然后:对carrage中的元素进⾏从左往右逐个遍历,如果符合下⼀个输出,则直接将其输出,并且遍历所有的缓冲轨道,查找是否有符合下⼀个输出的车厢,有的话便将其输出,否则将其压⼊缓冲轨道未经优化的代码:1 #include <iostream>2 #include <stack>3using namespace std;45 stack<int> stack_final;678void Output(int& minH, int& minS, stack<int> H[], int k, int n) {9// put the car from the strack to the output line, and change the minH and minS10int index; // the index of the car11//delete the minist car number from the minS12 stack_final.push(H[minS].top());13 H[minS].pop();14 cout << "Move car " << minH << "from holding track " << minS << " to output line" << endl;15//serch all the track's top, find the new minH and minS16 minH = n+2;17for (int i= 0; i < k; i++) {18if (!H[i].empty() && (index = H[i].top()) < minH) {19 minH = index;20 minS = i;21 }22 }23 }2425bool Input(int c, int& minH, int& minS, stack<int> H[], int k, int n) {26// put the new car c into the track27// if there is no available track, then return false, else return true28// find the best track for the car c29// initial30int BestTrack = 0; //the best track now31int BestTop = n+1; //the best track's top car32int index; //the index for the car33// search the k track34for (int i= 0; i < k; i++) {35if (!H[i].empty()) {36 index = H[i].top();37if (c < index && index < BestTop) {38//the top car's number is the smallest39 BestTop = index;40 BestTrack = i;41 }42 } else { // the track is empty43if (!BestTrack) {44 BestTrack = i;45 }46 }47 }48if (!BestTrack) {49return false; //there is available track to use50 }51 H[BestTrack].push(c);52 cout << "Move car " << c << "from input to holding track " << BestTrack << endl;53//if it is essencial, then change the minH and minS54if (c < minH) {55 minH = c;56 minS = BestTrack;57 }58return true;59 }6061bool Railroad(int input[], int n, int k) {62//k63// if it resort succed, then return true, else return false64// create the stack according to the k65 stack<int> *H;66 H = new stack<int> [k];67int NowOut = 1; // the next number of car to putout68int minH = n+1; //the minist number car in the k69int minS; //the minist number's strack70// resort the car71for (int i = n-1; i >= 0; i--) {72int number = input[i];73if (number == NowOut) {74 cout << "Move car " << number << " from the input line to the output line\n";75 stack_final.push(number);76 NowOut++;77while (minH == NowOut) {78 Output (minH, minS, H, k, n);79 NowOut++;80 }81 } else {82int end = 0;83for (int j = i; j > 0; j--) {84if (input[j-1] < input[j]) {85 end = j;86break;87 }88 }89for (int j = end; j <= i; j++) {90if (!Input (input[j], minH, minS, H, k, n)) {91return false;92 }93 }94if (end) {95 i = end;96 }97 }98 }99return true;100 }101102int main() {103int n, *input;104 cin >> n;105 input = new int[n];106for (int i = 0; i < n; i++) {107 cin >> input[i];108 }109if (Railroad(input, n, n-1)) {110 cout << "resort succed!\n";111while (!stack_final.empty()) {112 cout << stack_final.top() << "";113 stack_final.pop();114 }115 } else {116 cout << "failed\n";117 }118 }View Code经过优化之后的代码:增加的条件:车厢可以从排在后⾯的缓冲轨道移到前⾯的缓冲轨道。

迷宫问题 火车车厢重排问题 实验报告

迷宫问题 火车车厢重排问题 实验报告

实验报告了便于从列车上卸掉相应的车厢,车厢的编号应与车站的编号相同,这样,在每个车站只要卸掉最后一节车厢。

所以,给定任意次序的车厢,必须重新排列它们。

车厢的重排工作可以通过转轨站完成。

在转轨站中有一个入轨、一个出轨和k个缓冲轨,缓冲轨位于入轨和出轨之间。

假定缓冲轨按先进先出的方式运作,设计算法解决火车车厢重排问题。

②基本要求●设计存储结构表示n个车厢、k个缓冲轨以及入轨和出轨;●设计并实现车厢重排算法;●分析算法的时间性能。

③思考●如果缓冲轨按后进先出的方式工作,即用栈表示缓冲轨,应如何解决火车车厢重排问题?二、数据结构设计迷宫问题和火车重排问题可以通过栈与队列实现的。

迷宫的进出和车厢的出入轨和缓冲轨主要是对栈与队列的判断和操作。

int empty( STLink top[],int n) /*判断是否为空*/{return (top[n]==NULL);}int push(STLink top[],int A,int m) /*入栈*/{STLink p;if(!(p=(STLink)malloc(LEN)))return 0;else{p->data=A;p->link=top[m];top[m]=p;return 1;}}int pop(STLink top[],int m) /*出栈*/{int A;STLink p;p=top[m];A=p->data;top[m]=top[m]->link;free(p);return A;}struct Node{ /定义队列int data;Node* next;};三、算法设计1.迷宫问题:进入格子后,需要判断此时格子位置周围障碍物的位置,对其进行压栈,判断,然后看是否满足条件,满足就进栈,不满足就弹出,然后输出不能通过建立迷宫:typedef struct LStack{Element elem;struct LStack *next;}*PLStack;int InitStack(PLStack &S){S=NULL;return 1;}int StackEmpty(PLStack S){if(S==NULL)return 1;elsereturn 0;}int Push(PLStack &S, Element e){PLStack p;p=(PLStack)malloc(sizeof(LStack));p->elem=e;p->next=S;S=p;return 1;}(2).输出路径2.火车车厢排序六、实验收获与思考通过本次实验,进一步增强了对栈和队列的理解,明白的栈的先进后出和队列先进先出的方式,对压栈和出入栈与队列有了深刻认识。

实验2用堆栈解决火车车厢重排问题的编程

实验2用堆栈解决火车车厢重排问题的编程

实验2用堆栈解决火车车厢重排问题的编程一、目的通过对本次实验,我们应:1、加深对线性表、堆栈的认识;2、加深接口、类、索引器的认识;3、掌握堆栈数据结构,并应用堆栈编程解决实际问题。

二、实验准备1、软件准备:C#.net。

2、参考数据(示例):文件夹“…\实验2\示例”中的数据。

三、实验背景描述1、问题描述一列货运列车共有n节车厢,每节车厢将停放在不同的车站。

假定n个车站的编号分别为1 -n,货运列车按照第n站至第1站的次序经过这些车站。

车厢的编号与它们的目的地相同。

为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号1到n的次序排列。

当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。

我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲铁轨(位于入轨和出轨之间)。

图3.1a 给出了一个转轨站,其中有k= 3个缓冲铁轨H1,H2和H3。

开始时,n节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1至编号n的次序离开转轨站(通过出轨处)。

在图3.1a 中,n= 9,车厢从后至前的初始次序为5,8,1,7,4,2,9,6,3。

图3.1b 给出了按所要求的次序重新排列后的结果。

图2.1根据上面的描述,编写程序实现下面的功能:编写一算法实现火车车箱的重排;编写程序模拟图2.1所示的具有9节车厢的火车入轨和出轨的过程。

程序主界面设计如图2.2所示。

图2.22、问题分析为了重排车厢,需从前至后依次检查入轨上的所有车厢。

如果正在检查的车厢就是下一个满足排列要求的车厢,可以直接把它放到出轨上去。

如果不是,则把它移动到缓冲铁轨上,直到按输出次序要求轮到它时才将它放到出轨上。

缓冲铁轨上车厢的进和出只能在缓冲铁轨的尾部进行。

当缓冲铁轨上的车厢编号不是按照从顶到底的递增次序排列时,重排任务将无法完成。

新的车厢u应送入这样的缓冲铁轨:其底部的车厢编号v满足v>u,且v是所有满足这种条件的缓冲铁轨顶部车厢编号中最小的一个编号。

火车车厢重排问题栈c语言

火车车厢重排问题栈c语言

火车车厢重排问题栈c语言以下是一个用C语言实现火车车厢重排问题的代码:```c#include <stdio.h>#include <stdlib.h>#define MAX_SIZE 100typedef struct {int val;struct Node* next;} Node;typedef struct {Node* top;} Stack;Stack* createStack() {Stack* stack = (Stack*)malloc(sizeof(Stack));stack->top = NULL;return stack;}int isEmpty(Stack* stack) {return (stack->top == NULL);}void push(Stack* stack, int val) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->val = val;newNode->next = stack->top;stack->top = newNode;}int pop(Stack* stack) {if (isEmpty(stack)) {printf("Stack is empty.\n");return -1;}int val = stack->top->val;Node* temp = stack->top;stack->top = stack->top->next;free(temp);return val;}int peek(Stack* stack) {if (isEmpty(stack)) {printf("Stack is empty.\n");return -1;}return stack->top->val;}int canReorder(int numCars, int cars[]) { Stack* stationStack = createStack(); Stack* branchStack = createStack(); int nextCar = 1;for (int i = 0; i < numCars; i++) {// 如果当前车厢和需要出站的车厢一致,直接出站if (cars[i] == nextCar) {nextCar++;continue;}// 将从站台出来的车厢压入分支轨道while (!isEmpty(stationStack) && peek(stationStack) == nextCar) {push(branchStack, pop(stationStack));nextCar++;}// 当前车厢进站push(stationStack, cars[i]);}// 如果分支轨道中的车厢可以按顺序出站,则返回1,否则返回0while (!isEmpty(branchStack)) {if (pop(branchStack) != nextCar) {return 0;}nextCar++;}return 1;}int main() {int numCars;int cars[MAX_SIZE];printf("Enter the number of train cars: ");scanf("%d", &numCars);printf("Enter the train car numbers: ");for (int i = 0; i < numCars; i++) {scanf("%d", &cars[i]);}int result = canReorder(numCars, cars);if (result) {printf("Yes, it is possible to reorder the train cars.\n"); } else {printf("No, it is not possible to reorder the train cars.\n"); }return 0;}```输入示例:```Enter the number of train cars: 5Enter the train car numbers: 3 1 2 4 5```输出示例:```Yes, it is possible to reorder the train cars. ```。

火车车厢重排问题栈c语言

火车车厢重排问题栈c语言

火车车厢重排问题栈c语言火车车厢重排问题是一个经典的问题,考验了数据结构和算法的运用。

这个问题可以很好地帮助我们了解如何使用栈这种数据结构来解决实际问题,并且可以通过编写C语言程序对其进行求解。

在本文中,我们将深入探讨火车车厢重排问题,并编写C语言程序实现问题的求解。

首先,让我们来了解一下火车车厢重排问题的具体描述。

假设有一列火车车厢按照编号从1到n的顺序排列在轨道上。

现在我们需要将这些车厢按照特定的顺序重新排列,给定一个目标排列,我们需要找出一种排列车厢的方法,使得最终的排列符合目标排列。

具体而言,对于每一个车厢,我们可以将其从原来的位置移动到一个临时的缓冲轨道中,然后再将其移动到目标位置。

这个问题的关键在于如何确定每个车厢应该如何移动才能满足最终的目标排列。

为了解决这个问题,我们可以使用栈这种数据结构来辅助实现。

栈是一种先进后出的数据结构,这样的特性非常适合用来模拟火车车厢的重排过程。

具体而言,我们可以将原始轨道上的车厢编号序列作为输入,然后使用栈来模拟车辆的移动过程,最终得到目标排列。

下面我们将通过C语言程序来实现这个过程。

首先,我们需要定义一个栈的数据结构,来模拟车厢的移动过程。

我们可以使用数组来实现这个栈,同时需要定义一个栈顶指针来表示当前栈顶元素的位置。

另外,我们还需要定义一个函数来模拟入栈和出栈的过程。

接下来,让我们来具体实现这个栈的数据结构和相关的函数。

```c#include <stdio.h>#include <stdlib.h>#define MAX_SIZE 100typedef struct {int data[MAX_SIZE];int top;} Stack;void init(Stack *s) {s->top = -1;}void push(Stack *s, int value) { if (s->top < MAX_SIZE - 1) {s->top++;s->data[s->top] = value;} else {printf("Stack overflow\n");}}int pop(Stack *s) {if (s->top >= 0) {int value = s->data[s->top];s->top--;return value;} else {printf("Stack underflow\n"); return -1;}}int main() {Stack s;init(&s);//对栈进行入栈和出栈操作push(&s, 1);push(&s, 2);push(&s, 3);printf("%d\n", pop(&s)); //输出3printf("%d\n", pop(&s)); //输出2printf("%d\n", pop(&s)); //输出1printf("%d\n", pop(&s)); //输出Stack underflow,表示栈已空return 0;}```在这段代码中,我们定义了一个栈的数据结构,并实现了栈的初始化、入栈和出栈操作。

用堆栈解决编程问题(C#版)

用堆栈解决编程问题(C#版)

数据结构(C#语言版)

解决堆栈的编程问题
数据结构(C#语言版)
解决堆栈的编程问题
小结
在本章中,你已经学到:
堆栈(Stack)是一种特殊旳线性表,是一种只允许在表旳一端进行 插入或删除操作旳线性表。栈旳主要特点是“后进先出”; 堆栈旳插入操作也称为进栈或入栈,堆栈旳删除操作称为出栈 或退栈; 允许插入和删除旳一端称栈顶(Top),不允许插入和删除旳一端 称栈底(Bottom); 堆栈旳基本操作; 顺序栈用一片连续旳存储空间来存储栈中旳数据元素; 链栈是用链式存储构造存储旳栈。
使用堆栈处理编程问题
数据构造(C#语言版)
目的
在本章中,你将学到:
辨认堆栈旳特征 实施堆栈 利用堆栈来处理编程问题
数据结构(C#语言版)
解决堆栈的编程问题
学习情境——用堆栈处理火车车厢重排问题旳编 程
[问题描述]
一列货运列车共有n节车厢,每节车厢将停放在不同旳车站。假定n个 车站旳编号分别为1 -n,货运列车按照第n站至第1站旳顺序经过这些 车站。车厢旳编号与它们旳目旳地相同。为了便于从列车上卸掉相应 旳车厢,必须重新排列车厢,使各车厢从前至后按编号1到n旳顺序排 列。当全部旳车厢都按照这种顺序排列时,在每个车站只需卸掉最终 一节车厢即可。我们在一种转轨站里完毕车厢旳重排工作,在转轨站 中有一种入轨、一种出轨和k个缓冲铁轨(位于入轨和出轨之间)。图 3.1a 给出了一种转轨站,其中有k= 3个缓冲铁轨H1,H2和H3。开始 时,n节车厢旳货车从入轨处进入转轨站,转轨结束时各车厢从右到 左按照编号1至编号n旳顺序离开转轨站(经过出轨处)。在图3.1a 中, n= 9,车厢从后至前旳初始顺序为5,8,1,7,4,2,9,6,3。图 3.1b 给出了按所要求旳顺序重新排列后旳成果。

数据结构车厢调度实习报告

数据结构车厢调度实习报告

实习报告:2.3题车厢调度实习报告题目:假设停在铁路调度站入口处的车厢序列的编号次序为1,2,3,…,n。

设计一个程序,求出所有可能输出的长度为n的车厢序列。

班级:计算机(2)班姓名:李伟学号:07095216 完成日期:2009.9.9一、需求分析1、用编号依次为1,2,3,……,n表示停在铁路调度站入口处的车厢序列。

2、用一个栈形象地表示为火车的调度站。

3、利用栈先进后出的性质,结合递归和回溯算法,实现编号1…n的车厢的所有可能的序列。

4、本程序用C语言实现,已经在WIN-TC环境下通过。

二、概要设计1、设定栈的抽象数据类型定义:ADT Stack{数据对象:D={ai | ai∈CharSet,i=1,2,……,n,n≥0}数据关系:R1={<ai-1,ai> | ai-1,ai∈D,i=2,……,n}基本操作:InitStack(&S)操作结果:构造一个空栈S。

Push(&S,e);初始条件:栈S已存在。

操作结果:在栈S的栈顶插入新的栈顶元素e。

Pop(&S,e);初始条件:栈S已存在。

操作结果:删除S的栈顶元素,并以e返回其值。

StackEmpty(S)初始条件:栈S已存在。

操作结果:若S为空栈,则返回TRUE,否则返回FALSE。

}ADT Stack2、本程序包括两个模块:(1)初始化数据——输入总数——初始化栈和序列(2)显示所有的序列——递归调用——输出所有结果三、详细设计1、为了使车厢能够调度,需要定义一个栈,利用栈先进后出的性质,改变车厢的顺序;因为输出的序列有很多种,而且序列的产生是用递归产生的,所以定义一个二维数组,用它保存所有的输出序列,供演示时调用。

struct pathss{int paths[MAXSIZE][MAXSIZE];int number;}AllPath;2、栈类型struct SNode{int data[MAXSIZE];int top;}S;栈的基本操作:void InitStack() /*栈的初始化*/{S.top=-1;}void Push(int q) /*进栈*/{S.data[++S.top]=q;}int Pop() /*出栈*/{int temp;temp=S.data[S.top--];return temp;}int StackEmpty() /*判断栈是否为空*/ {if(S.top==-1)return 1;elsereturn 0;}3、求所有序列的伪码算法:void Attemper(int pos,int path[],int cur){if(pos<n) {一个数进栈后,有两种处理方式:要么立刻出栈,要么进行下一个数的进栈}if(栈不空){一个数出栈后,有两种处理方式:要么继续出栈,要么继续下一个数的进栈}if(pos==n && 栈空){一种可能输出序列产生,输出;并将每种序列保存在二维数组里;}}4、演示一种序列的伪码算法:演示时,采用的是向逆推的方法,因为我们已经知道了一种输出序列的结果和它的最初状态,就可以利用栈将中间过程显示出来;void ChooseDisplay(){int k,Output,Input=1;for(Output=0;Output<n;Output++){if(输出序列中当前的数据大于等于入口处的数据时){while(输出序列中当前的数据大于等于入口处的数据时){入口处的数据要一直压栈}显示每一步结果}else (序列中当前的数据小于入口处的数据){弹出栈顶,重新显示结果}}}5、主函数和其他函数void main() /*主函数*/{功能选择分别调用:1: InputNumber()2: DisplayAll()}void DisplayAll() /*显示所有输出序列*/{调用函数Attemper}void DisplayOnly(int k,int Output,int Input) /*显示操作序列的状态的变化过程*/ {第一步:显示输出序列的状态变化第二步:显示栈的状态变化}6、函数的调用关系图反映了演示程序的层次结构:四、调试分析1、本程序的栈其实也是一个一维数组,然后用一个top作为指针,控制数组的长度。

车厢调度问题解析(经典递归)

车厢调度问题解析(经典递归)

车厢调度问题解析(经典递归)博客分类:zhanghonglun•算法算法题目假设停在铁路调度站入口处的车厢系列的编号依次为1,2,3,…n。

设计一个程序,求出所有可能由此输出的长度为n 的车厢系列。

解析:一个数的进栈以后,有两种处理方式:要么立刻出栈,或者下一个数的进栈(如果还有下一个元素)其出栈以后,也有两种处理方式:要么继续出栈(栈不为空),或者下一个数的入栈。

该问题有天然的递归性质算法设计:两重递归,下一个元素处理完后返回,再处理出栈的递归,有点像嵌套循环,但比它复杂...进栈的递归跳出条件为最后一个元素进栈出栈的递归跳出条件为栈空附上经典实现代码C代码1.#include<stdafx.h>2.#include<stdio.h>3.#define MaxLen 1004.struct snode{5.int data[MaxLen];6.int top;7.}s;//定义一个栈指针8.int n;//定义输入序列总个数9.void Initstack()10.{11. s.top=-1;12.}13.void push(int q)//元素n进栈14.{15. s.top++;16. s.data[s.top]=q;17.}18.int pop()//出栈19.{20. int temp;21. temp=s.data[s.top];22. s.top--;23. return temp;24.}25.int Emptys()//判断栈空26.{27. if(s.top==-1)28. return 1;29. else30. return 0;31.}32./*33.每次调用求值阶段包含两重递归,只有全部返回,才表示本pos 处理完,可以对上一个元素求值,process 就是找出当前元素进栈后所有可能的操作,即在当前元素进栈后各种情况下,34.包括不出栈,立即出栈,出栈后继续出栈情况(出栈递归)下,继续处理下一个元素(入栈递归)35.36.*/37.void process(int pos,int path[],int curp)//当前处理位置pos的元素38.{39. int m,i;40. if(pos<n)//编号进栈递归41. {42. push(pos+1);//当前元素进栈后下一个元素继续进栈43. process(pos+1,path,curp); //处理下一个元素,返回表明下一个元素进栈的情况处理完了44. pop(); //下一个元素处理完后,pop 掉,准备处理直接出栈45. }46.47. if(!Emptys())//递归处理出栈48. {49. m=pop();50. path[curp]=m;51. curp++;52. process(pos,path,curp);//出栈后处理下一个素继续进栈53. push(m);54. }55. if(pos==n&&Emptys())//输出一种可能的方案56. {57. for(i=0;i<curp;i++)58. printf("%2d",path[i]);59. printf("\n");60. }61.}62.void main()63.{64. int path[MaxLen];65. printf("输入要调度车厢总数:");66. scanf("%d",&n);67. Initstack();68. push(1);69. printf("所有输出序列:\n");70. process(1,path,0); //从1 开始,递归处理所有元素71.}。

数据结构之火车厢重排

数据结构之火车厢重排

目录一、功能描述 (2)1、输入火车厢信息 (2)2、入轨 (2)3、出轨 (2)4、退出 (2)二、总体概要设计 (2)1、系统设计框图: (2)2、系统设计流程图 (3)三、详细设计 (3)1 功能一:输入火车厢信息 (3)1)概要设计: (3)2)算法描述: (3)3)算法分析 (4)2 功能二:入轨 (4)1)概要设计: (4)2)算法描述: (4)3)算法分析: (7)3 功能三:出轨 (8)1)概要设计 (8)2)算法描述: (8)3)算法分析: (11)4 功能四:退出 (11)四、效果及存在问题 (11)1、效果显示: (11)1)输入火车厢信息 (12)2)入轨 (12)3)出轨: (12)4)显示重排完成车厢排列 (13)2、存在问题 (13)五、心得及体会 (14)六、参考文献 (14)七、评分表(见尾页).............................. 错误!未定义书签。

附录:源代码. (14)一、功能描述1、输入火车厢信息设置欢迎界面,引导用户输入火车厢总长及原始火车厢排列,给系统提供必要数据信息。

2、入轨给出每节火车厢对应转入的缓冲铁轨提示,并显示所需缓冲铁轨数。

3、出轨给出每节火车厢出轨提示。

4、退出如果不需要操作就退出系统。

二、总体概要设计建立一个堆栈数组及栈顶指针数组,将所有的车厢都压入到堆栈(缓冲铁轨)中,入轨方法是使得每个堆栈里的元素从栈底到栈顶都是依次递减的,每次单节车厢出栈时,只要找到最小的栈顶元素令其依次出栈便可得到排好序的火车厢排列。

1、系统设计框图:2、系统设计流程图三、详细设计1 功能一:输入火车厢信息1)概要设计:通过printf语句设置欢迎界面及显示让用户输入火车厢总长及火车原始排列信息,并在屏幕上显示火车原始排列。

2)算法描述:流程图:在总流程图已经画出中,此处不再累述功能代码:int i,M,A[100],N=0;printf("\n\n");printf("************************************************************\n\n"); printf("===============您好,欢迎光临火车转轨系统!===============\n\n");printf("请输入您要进行转轨的火车车厢总长:");scanf("%d",&M);printf("\n请输入未转轨前车厢的排列顺序,请不要重复输入相同且不要遗漏输入车厢号\n\n");for(i=0;i<M;i++){scanf("%d",&A[i]);}printf("未转轨前的火车厢排列如下,请核对:\n");for(i=0;i<M;i++)printf("A[%d]=%d\n",i,A[i]);3)算法分析:此功能模块简单明了没有深度算法,在此不做分析。

数据结构 车厢问题 实验报告

数据结构 车厢问题 实验报告

数据结构实验报告实验名称:实验二——题目5学生姓名:班级:班内序号:学号:日期:2011年11月7日1.实验要求利用队列结构实现车厢重排问题。

车厢重排问题如下:一列货车共有n节车厢,每个车厢都有自己的编号,编号范围从1~n。

给定任意次序的车厢,通过转轨站将车厢编号按顺序重新排成1~n。

转轨站共有k个缓冲轨,缓冲轨位于入轨和出轨之间。

开始时,车厢从入轨进入缓冲轨,经过缓冲轨的重排后,按1~n的顺序进入出轨。

缓冲轨按照先进先出方式,编写一个算法,将任意次序的车厢进行重排,输出每个缓冲轨中的车厢编号。

2. 程序分析将每个轨道视为一个队列,每一个车厢视为一个结构体的结点,结点存储车厢编号以及下一节车厢的地址。

用尾插法建立队列,并根据队列队尾入队,队头出队的特点实现结点的出队以及入队。

由于车厢在重排过程中将会频繁进行入队以及出队的操作,如果采用顺序存储结构,则在结点出入队时是操作将会十分不方便,还会占用大量多余的空间和时间,故选用链式存储结构,可以直接调动结点,十分简洁。

重排过程比如:编号为3的车厢进入缓冲轨1,则下一个编号小于3的车厢则必须进入下一个缓冲轨2,而编号大于3的车厢则进入缓冲轨1,排在3号车厢的后面。

在把车厢c 移至缓冲轨是,车厢c应该移动到这样的缓冲轨中:该缓冲轨中队尾车厢的编号小于c;如果有多个缓冲轨满足这一条件,则选择对位车厢编号最大的缓冲轨,否则选择一个空的缓冲轨。

这样,出轨的时候才可以按照从小到大的顺序重新编排。

2.1 存储结构2.2 关键算法分析1. 移动车厢算法(车厢要从a队列移至b队列)·自然语言描述(1)判断a队列是否为空,为空则输出“队列下溢”,提示出错。

(2) 否则,设置工作指针p 指向a 队列的队头元素,(3) 将b 的尾指针指向next 域指向p ;(4) b 队列的尾指针后移,指向p 指向的结点;(5) a 头结点指向p 后一个结点(6) p 的next 域置为空,完成一次车厢的移动(7) a 队列车厢数减1,b 队列车厢数加1·伪代码描述两个队列,车厢要从a 队列移至b 队列;(1)bus* p=a.front->next;(2)if(!p) cout<<"Underflow"<<endl;(3)b.rear->next=p;(4)b.rear=b.rear->next;(5)a.front->next=p->next;(6)p->next=NULL;(7)if(!(a.front->next))a.rear=a.front;(8)a.Number--;b.Number++;图示ab算法时间复杂度O(1),空间复杂度S(1)。

c++数据结构用队列实现火车车厢重排问题,分头文件的完整面向对象代码

c++数据结构用队列实现火车车厢重排问题,分头文件的完整面向对象代码
int i=0;
bool flag=1;//标记
while(i<n&&flag){ //当入轨中有车厢时
flag=0;
for(int m=0;m<k;m++){ //判断缓冲轨的队尾元素与入轨的元素
if(a[m].GetRear()<arr[i]){
a[m].EnQueue(arr[i]);
}
friend void TrainPermute(int arr[],LinkQueue<T> a[],int n,int k);
};
template<typename T>
LinkQueue<T>::LinkQueue(){
Node<T> *s=new Node<T>;
s->next=NULL;
if(rear==front)
throw"下溢";
Node<T> *p=front->next;
int x=p->data;
front->next=p->next;
if(p->next==NULL)
rear=front;
delete p;
return x;
}
}
else
{
for(int m=0;m<k;m++){
cout<<"第"<<(m+1)<<"个缓冲轨的列车编号\t";
a[m].Trans();
cout<<endl;

C++火车车厢重排问题

C++火车车厢重排问题

cout<<endl; cout<<"请问是手动输入车厢号还是随机产生? \n1 手动 2 随机 " <<endl;
cin>>h; switch(h) {case 1: cout<<endl; for(a=0;a<n;a++) cin>>array[a]; break; case 2: srand((unsigned)time(NULL)); int count=0; int *m; m=new int[n]; while(count!=n) { t=rand()%n; if(m[t]!=1) { array[t]=count+1; m[t]=1; count++; } } break;
}
cout<<endl; cout<<"火车车厢入轨顺序为:"<<endl; for(int i=0;i<n;i++) cout<<array[i]<<" "; cout<<endl; LinkQueue *buffer; buffer=new LinkQueue[k]; cout<<endl; TrainPermute(array,buffer,n,k); cout<<endl;} //缓冲轨
bool Empty() {if(front==NULL) return 1; else return 0;}
//判断队空
friend void TrainPermute(int arr[],LinkQueue a[],int n,int k); private: Node *front,*rear; };

顺序栈--问题描述2

顺序栈--问题描述2

问题描述某城市有一个火车站,有n节车厢从A方向驶入车站,按进站的顺序编号为1~n。

现让它们按照某种特定的顺序进入B方向的铁轨并驶出车站。

为了重组车厢,你可以借助中转站C。

在程序中输入车厢数目和出站的特定顺序,如果可以则输出Yes,否者输出No。

(C是一个可以停放任意多节车厢的车站,但由于末端封顶,驶入C的车厢必须按照相反的顺序驶出C。

对于每个车厢,一旦从A移入C,就不能再回到A了;一旦从C移入B,就不能回到C了。

换句话说,在任意时刻,只有两种选择:A–>C和C–>B。

)样例输入:51 2 3 4 555 4 1 2 366 5 4 3 2 1样例输出:YesNoYes#include<stdio.h>int main(){int a[1001],b[1001];// a数组存放A方向顺序编号的1-n的车厢b数组存放特定顺序进入B方向铁轨的车厢编号int n,i,j,k; //n表示车厢while(scanf("%d",&n)==1){i=0;for(j=1;j<=n;j++)scanf("%d",&b[j]);for(k=1,j=1;k<=n;k++){a[++i]=k;while(a[i]==b[j] && i>0 && j<=n){i--;j++;}}if(i==0)printf("Yes\n");elseprintf("No\n");;}return 0;}。

栈与队

栈与队

栈与队实验原理:用栈实现顺序表的操作实验目的:1.掌握栈的数据类型描述,栈的特点及栈的存储结构;2.掌握栈的基本运算及应用.实验内容:设车辆厂生产了硬座车厢和软座车厢共N节,混合在一起要求用顺序栈的5种运算使所有的硬座车厢排列到软座车厢前面。

请完善主函数实现上述功能。

实验步骤:1、输入示例程序2、构建按序插入函数实现算法3、用C语言实现该算法4、与源程序合并,编译,调试5、测试,查错,修改6、生成可执行文件,通过综合测试,完成实验代码区:#include<iostream>using namespace std;const int maxlen=20;struct seqstack{char stack[maxlen];int top;};//栈初始化void inistack(seqstack &s) {s.top=0;}//进栈void push(seqstack &s,char x) {if(s.top==maxlen-1)cout<<"overflow";else{s.top++;s.stack[s.top]=x;}}//出栈void pop(seqstack &s){if(s.top==0)cout<<"underflow";elses.top--;}//取栈顶元素char gettop(seqstack &s){if(s.top==0){cout<<"underflow";return 0;}elsereturn s.stack[s.top];}//判别栈是否为空int empty(seqstack &s){if(s.top==0)return 1;elsereturn 0;}//打印栈内容void prtstack(seqstack &s){int i;for(i=0;i<=s.top;i++){cout<<s.stack[i]<<endl;}}int main(){int n,i;char x;seqstack s1,s2;inistack(s1);inistack(s2);cout<<"请输入车厢数\n";cin>>n;cout<<"请输入"<<n<<"节车厢代号(H 硬座车厢 S 软座车厢)";for(i=0;i<n;i++){cin>>x;if(x=='H')push(s1,x);if(x=='S')push(s2,x);}prtstack(s1);prtstack(s2);return 0;}实验总结:本实验的重点在于对栈模式的理解。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验2用堆栈解决火车车厢重排问题的编程
一、目的
通过对本次实验,我们应:
1、加深对线性表、堆栈的认识;
2、加深接口、类、索引器的认识;
3、掌握堆栈数据结构,并应用堆栈编程解决实际问题。

二、实验准备
1、软件准备:C#.net。

2、参考数据(示例):文件夹“…\实验2\示例”中的数据。

三、实验背景描述
1、问题描述
一列货运列车共有n节车厢,每节车厢将停放在不同的车站。

假定n个车站的编号分别为1 -n,货运列车按照第n站至第1站的次序经过这些车站。

车厢的编号与它们的目的地相同。

为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号1到n的次序排列。

当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。

我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲铁轨(位于入轨和出轨之间)。

图3.1a 给出了一个转轨站,其中有k= 3个缓冲铁轨H1,H2和H3。

开始时,n节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1至编号n的次序离开转轨站(通过出轨处)。

在图3.1a 中,n= 9,车厢从后至前的初始次序为5,8,1,7,
4,2,9,6,3。

图3.1b 给出了按所要求的次序重新排列后的结果。

图2.1
根据上面的描述,编写程序实现下面的功能:
编写一算法实现火车车箱的重排;
编写程序模拟图2.1所示的具有9节车厢的火车入轨和出轨的
过程。

程序主界面设计如图2.2所示。

图2.2
2、问题分析
为了重排车厢,需从前至后依次检查入轨上的所有车厢。

如果正在检查的车厢就是下一个满足排列要求的车厢,可以直接把它放到出轨上去。

如果不是,则把它移动到缓冲铁轨上,直到按输出次序要求
轮到它时才将它放到出轨上。

缓冲铁轨上车厢的进和出只能在缓冲铁轨的尾部进行。

当缓冲铁轨上的车厢编号不是按照从顶到底的递增次序排列时,重排任务将无法完成。

新的车厢u应送入这样的缓冲铁轨:其底部的车厢编号v满足v>u,且v是所有满足这种条件的缓冲铁轨顶部车厢编号中最小的一个编号。

只有这样才能使后续的车厢重排所受到的限制最小。

3、堆栈的基本操作
初始化栈:也就是产生一个新的空栈;
入栈操作Push(T x):将指定类型元素x进到栈中;
出栈操作Pop(): 将栈中的栈顶元素取出来,并在栈中删除栈
顶元素;
取栈顶元素GetTop():将栈中的栈顶元素取出来,栈中元素不
变;
判断栈空IsEmpty():若栈为空,返回true,否则返回false;
清空操作Clear ( ):从栈中清除所有的数据元素。

四、实验内容
1、应用顺序存储结构(顺序栈)编程实现火车车厢重排;
2、应用链式存储结构(单链栈)编程实现火车车厢重排。

相关文档
最新文档