C++栈类火车调度问题MFC栈类
Posted bcbobo21cn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++栈类火车调度问题MFC栈类相关的知识,希望对你有一定的参考价值。
先看一下C++基本栈类的使用;
#include "stdafx.h"
#include<iostream>
#include <stack>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
stack<int> s;
s.push(0);
s.push(303);
s.push(909);
s.pop();
cout << s.top() << endl;
return 0;
然后看火车调度问题;
这题大概是ACM里的基础题;题目描述如下;
设有编号为1,2,3,4,5,6~~~n的n辆列车,顺序进入一个栈式结构的站台。列出这n辆车的所有可能出站的顺序。
Input:
输入列车辆数和编号
Output:
输入所有列车出站的序列用空格隔开车编号
Sample Input:
3
1 2 3
Sample OutPut:
1 2 3
1 3 2
2 3 1
2 1 3
3 2 1
栈和车是如下示意的;
可以全部开进栈,再往B端出;或先进去3个、2个、1个,再调度往B端出;
某些排列是不可能的;
编程实现起来用栈比较方便;
网上找到一个程序,它的样例输入输出如下;
Input
5 2
1 2 3 5 4
Output
push
pop
push
pop
push
pop
push
push
pop
pop
第一行输入2个整数:车数量,先进到栈里的车数量;
第二行输入一种排列;
如果排列可行,则输出操作序列,如果排列不可行,则输出no;
代码如下;
// hcddtest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <stack>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
int a[50], c[50];
bool operation[50];
int i = 0;
int t, t1, m, m1 = 0, n, i1 = 0;
cin >> t;
for (t1 = 0; t1 < t; t1++)
cin >> n >> m;
for (i = 0; i < n; i++)
cin >> a[i];
int step = 0, b = 1;
stack<int>s;
s.push(0);
for (i = 0; i < n; i++)
while (s.top() < a[i])
s.push(b++);
operation[step++] = true;
if (s.size()>m + 1)
cout << "no\\n";
i1 = 1;
break;
if (s.top() == a[i])
s.pop();
operation[step++] = false;
if (i1 != 1)
if (s.size() == 1 && s.top() == 0)
for (i = 0; i < step; i++)
if (operation[i] == true) cout << "push\\n";
else cout << "pop\\n";
else cout << "no\\n";
return 0;
但是程序还有点小问题;目前没时间看;输出有些问题,
总之要理解题目、数据结构栈才能做;
然后看一下MFC里面,可能没有栈类;网上找到一个栈类;
#pragma once
#ifndef STACK_H_
#define STACK_H_
#include<iostream>
//结点结构体,双向栈
template<class T>
struct StackNode
T _tData; //数据域
StackNode<T>* _pNext; //指针域,指向下一结点
StackNode<T>* _pLast; //指针域,指向上一结点(为了行编辑器函数的实现)
StackNode(StackNode<T>* next = nullptr,
StackNode<T>* last = nullptr) //用指针构造函数
this->_pNext = nullptr;
this->_pLast = nullptr;
StackNode(T data, StackNode<T>* next = nullptr,
StackNode<T>* last = nullptr) //用指针构造函数
this->_tData = data;
this->_pNext = next;
this->_pLast = last;
;
template<class T>
class Stack
private:
StackNode<T>* _pTop; //栈顶指针
StackNode<T>* _pBottom; //栈底指针,为了方便行编辑器使用
int _iConuntOfElement; //结点数量
public:
Stack(); //构造函数
Stack(Stack<T>& copy); //构造函数
~Stack(); //析构函数
bool IsEmpty(); //判断栈是否为空
void MakeEmpty(); //将栈中的元素全部删除
void Put(const T data); //顶端插入数据
int Size() return _iConuntOfElement; //返回栈中的结点数
void GetTop(T& data); //获取顶端结点
void Pop(T& data); //顶端弹出结点,并将元素传至参数中
void Traverse(); //逆序栈中的结点
void DisPlay(bool forward = true); //输出函数,默认正向输出
;
//构造函数,为栈顶和栈底分配内存
template<class T>
Stack<T>::Stack()
_pTop = _pBottom = nullptr;
this->_iConuntOfElement = 0;
//拷贝构造函数
//缺少此函数,在传参与析构的时候容易出问题
template<class T>
Stack<T>::Stack(Stack<T>& copy)
StackNode<T>* pCur = this->_pTop; //建立指针,用于遍历本对象中的结点
while (pCur) //遍历本对象的结点
T data = pCur->_tData; //依此取出结点值
copy.Put(data); //插入到copy栈中
pCur = pCur->_pNext;
//析构函数
template<class T>
Stack<T>::~Stack()
MakeEmpty(); //释放结点内存
this->_pTop = this->_pBottom = nullptr; //将指针指向空,避免出现野指针
//判断栈是否为空
template<class T>
bool Stack<T>::IsEmpty()
if (!this->_pTop) //如果栈对象没有头节点,那么栈就为空
return true;
return false;
//将栈中的元素全部删除
template<class T>
void Stack<T>::MakeEmpty()
StackNode<T>* pDel = nullptr; //建立临时结点指针,用于释放结点内存
while (_pTop) //循环依此从顶端删除
pDel = this->_pTop;
this->_pTop = _pTop->_pNext;
delete pDel;
_iConuntOfElement = 0; //栈结点数量置零
//顶端插入数据
template<class T>
void Stack<T>::Put(const T data)
StackNode<T>* newData = new StackNode<T>(data); //为新结点分配内存,新结点的并确定结点指针指向
if (!newData) //如果内存分配错误
std::cerr << "内存分配错误!" << std::endl;
exit(-1);
if (this->IsEmpty()) //如果插入的是第一个结点
newData->_pLast = nullptr; //将这个结点的指向上一下一结点的指针都赋空值
newData->_pNext = nullptr;
this->_pTop = newData; //将栈顶和栈底指针都指向这个结点
this->_pBottom = newData;
++this->_iConuntOfElement; //节点数加1
return;
this->_pTop->_pLast = newData; //栈顶的上一结点指针指向新结点
newData->_pNext = this->_pTop; //将新结点的下一结点指针指向栈顶
this->_pTop = newData; //新结点作为栈顶
++this->_iConuntOfElement;
//获取顶端结点
template<class T>
void Stack<T>::GetTop(T& data)
if (this->IsEmpty()) //栈为空,直接返回
return;
data = this->_pTop->_tData; //获取栈顶元素,赋值给返回参数
return;
//顶端弹出元素,并将元素传至参数中
template<class T>
void Stack<T>::Pop(T& data)
if (this->IsEmpty()) //栈为空,直接返回
return;
data = this->_pTop->_tData; //先取出栈顶的值
StackNode<T>* pDel = this->_pTop;
if (this->_pTop->_pNext) //如果有后继结点,就将后继结点的上一个指针指向空
this->_pTop->_pNext->_pLast = nullptr;
this->_pTop = this->_pTop->_pNext;
delete pDel; //释放原栈顶内存
--this->_iConuntOfElement; //栈结点数量递减
return;
delete pDel; //如果就只有一个结点,直接释放原栈顶的空间
this->_pTop = this->_pBottom = nullptr; //没有后继结点,释放栈顶空间,将指针指向空,避免出现野指针
--this->_iConuntOfElement; //栈结点数量递减
return;
//逆序栈中的结点
template<class T>
void Stack<T>::Traverse()
StackNode<T>* pCur = this->_pTop;
StackNode<T>* pTmp = nullptr; //临时指针,循环要用
while (pCur) //循环将栈中结点的前驱与后继指针对调
pTmp = pCur->_pLast;
pCur->_pLast = pCur->_pNext;
pCur->_pNext = pTmp;
pCur = pCur->_pLast; //这个是很值得细细品味的
//将栈顶与栈顶指针对调
pTmp = this->_pTop;
this->_pTop = this->_pBottom;
this->_pBottom = pTmp;
return;
//输出函数
template<class T>
void Stack<T>::DisPlay(bool forward = true)
StackNode<T>* pCur;
if(forward == true)
pCur = this->_pTop;
else
pCur = this->_pBottom;
while (pCur) //如果当前指针不为空,就一直循环遍历
std::cout << pCur->_tData; //为了照顾
//if (iCount % 10 == 0) //每隔十个换一行,以免输出的太长
// std::cout << std::endl;
if (forward == true)
pCur = pCur->_pNext;
else
pCur = pCur->_pLast;
std::cout << std::endl;
#endif // !STACK_H_
调用的代码如下;
void CssView::OnDraw(CDC* pDC)
CssDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CString str1;
Stack<CString> mystack;
mystack.Put(_T("AAA"));
mystack.Put(_T("BBB"));
mystack.Put(_T("CCC"));
mystack.Put(_T("DDD"));
mystack.GetTop(str1);
pDC->TextOutW(50,50, str1);
str1.Format(_T("%d"), mystack.Size());
pDC->TextOutW(50,80, str1);
CString strTopOfInfix = _T("");
mystack.Pop(strTopOfInfix);
mystack.GetTop(str1);
pDC->TextOutW(50,110, str1);
输出如下;
看上去这个类可用;下回继续;
以上是关于C++栈类火车调度问题MFC栈类的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode练习(Python):栈类:第145题:二叉树的后序遍历:给定一个二叉树,返回它的 后序 遍历。
Leetcode练习(Python):栈类:第145题:二叉树的后序遍历:给定一个二叉树,返回它的 后序 遍历。