栈 - 从零开始实现by C++
参考链接:数据结构探险—栈篇
学了队列之后,栈就很简单了,换汤不换药。
栈
栈的模型
后进先出(电梯,进制转换,括号的匹配检测)
栈的基本元素
栈顶,栈底(一般很少用到),栈容量,栈长度
注意:栈顶一般指向栈最后一个元素的下一位
标准C++代码
//MyStack.h #pragma once class MyStack { public: MyStack(int size); ~MyStack(); bool stackEmpty(); bool stackFull(); void clearStack(); int stackLength(); bool push(char elem); bool pop(char &elem); void stackTraverse(); private: char *m_pBuffer; int m_iSize; int m_iTop; };
//MyStack.cpp #include"MyStack.h" #include<iostream> using namespace std; MyStack::MyStack(int size) { m_iSize = size; m_pBuffer = new char[size]; m_iTop = 0; } MyStack::~MyStack() { delete[]m_pBuffer; } bool MyStack::stackEmpty() { if (0 == m_iTop) { return true; } return false; } bool MyStack::stackFull() { if (m_iTop == m_iSize) { return true; } return false; } void MyStack::clearStack() { m_iTop = 0; } int MyStack::stackLength() { return m_iTop; } bool MyStack::push(char elem) { if (stackFull()) { return false; } m_pBuffer[m_iTop] = elem; m_iTop++; return true; } bool MyStack::pop(char &elem) { if (stackEmpty()) { return false; } m_iTop--; elem = m_pBuffer[m_iTop]; return true; } void MyStack::stackTraverse() { for (int i = 0; i < m_iTop; i++) { cout << m_pBuffer[i] << ","; } }
//demo.cpp #include<iostream> #include"MyStack.h" using namespace std; int main() { MyStack *p = new MyStack(5); p->push('h'); p->push('e'); p->push('l'); p->push('i'); p->push('z'); p->stackTraverse(); char tmp = 0; p->pop(tmp); cout << endl << "ding is " << tmp << endl; p->clearStack(); cout << p->stackLength() << endl; if (p->stackEmpty()) { cout << "stack is empty" << endl; } if (p->stackFull()) { cout << "stack is full" << endl; } delete p; p = nullptr; return 0; }
改变栈元素的类型
#pragma once class Coordinate { public: Coordinate(int x = 0, int y = 0); void printCoordinate(); private: int m_iX; int m_iY; };
#include"Coordinate.h" #include<iostream> using namespace std; Coordinate::Coordinate(int x, int y) { m_iX = x; m_iY = y; } void Coordinate::printCoordinate() { cout << "(" << m_iX << "," << m_iY << ")" << endl; }
#include<iostream> #include"MyStack.h" using namespace std; /******************************************/ /* 栈类 要求: 1.定义Coordinate坐标类 2.改造栈类,使其可以适用于坐标类 目的:灵活掌握栈机制,理解抽象数据类型在栈中的应用 */ /******************************************/ int main() { MyStack *p = new MyStack(5); p->push(Coordinate(1,2)); p->push(Coordinate(3,4)); p->stackTraverse(); Coordinate tmp = 0; p->pop(tmp); cout << endl << "tmp is "; tmp.printCoordinate(); p->clearStack(); cout << "Length: " << p->stackLength() << endl; if (p->stackEmpty()) { cout << "empty" << endl; } if (p->stackFull()) { cout << "full" << endl; } delete p; p = nullptr; return 0; }
类模板重写栈
#pragma once #include<ostream> using namespace std; class Coordinate { friend ostream &operator<<(ostream &out, Coordinate &coor); public: Coordinate(int x = 0, int y = 0); void printCoordinate(); private: int m_iX; int m_iY; };
#include"Coordinate.h" #include<iostream> using namespace std; Coordinate::Coordinate(int x, int y) { m_iX = x; m_iY = y; } void Coordinate::printCoordinate() { cout << "(" << m_iX << "," << m_iY << ")" << endl; } ostream &operator<<(ostream &out, Coordinate &coor) { out << "(" << coor.m_iX << "," << coor.m_iY << ")" << endl; return out; }
#pragma once template <typename T> class MyStack { public: MyStack(int size); //分配内存初始化栈空间,设定 栈容量,栈顶 ~MyStack(); //回收栈空间内存 bool stackEmpty(); //判定栈是否为空,为空返回true,非空返回false bool stackFull(); //判定栈是否为满,为满返回true,不满返回false void clearStack(); //清空栈 int stackLength(); //已有元素的个数 bool push(T elem); //元素入栈,栈顶上升 bool pop(T &elem); //元素出栈,栈顶下降 void stackTraverse(); //遍历栈中所有元素 private: T *m_pBuffer;//栈空间指针 int m_iSize; //栈容量 int m_iTop; //栈顶,栈中元素个数 }; //不支持分开编译 template <typename T> MyStack<T>::MyStack(int size) //分配内存初始化栈空间,设定 栈容量,栈顶 { m_iSize = size; m_pBuffer = new T[size]; m_iTop = 0; } template <typename T> MyStack<T>::~MyStack() //回收栈空间内存 { delete[]m_pBuffer; m_pBuffer = nullptr; } template <typename T> bool MyStack<T>::stackEmpty()//判定栈是否为空,为空返回true,非空返回false { if (0 == m_iTop) { return true; } return false; } template <typename T> bool MyStack<T>::stackFull() //判定栈是否为满,为满返回true,不满返回false { if (m_iTop == m_iSize) { return true; } return false; } template <typename T> void MyStack<T>::clearStack() //清空栈 { m_iTop = 0; } template <typename T> int MyStack<T>::stackLength() //已有元素的个数 { return m_iTop; } template <typename T> bool MyStack<T>::push(T elem) //元素入栈,栈顶上升 { if (stackFull()) { return false; } m_pBuffer[m_iTop] = elem; m_iTop++; return true; } template <typename T> bool MyStack<T>::pop(T &elem) //元素出栈,栈顶下降 { if (stackEmpty()) { return false; } m_iTop--; elem = m_pBuffer[m_iTop]; return true; } template <typename T> void MyStack<T>::stackTraverse() //遍历栈中所有元素 { for (int i = 0; i < m_iTop; i++) { //m_pBuffer[i].printCoordinate();//可以使用运算符重载 cout << m_pBuffer[i]; } }
#include<iostream> #include"MyStack.h" using namespace std; #include"Coordinate.h" /******************************************/ /* 栈 类模板 要求: 将普通栈改造为类模板栈,使其可以适用于任何数据类型 目的:灵活掌握栈机制,理解抽象数据类型在栈中的应用 */ /******************************************/ int main() { MyStack<Coordinate> *p = new MyStack<Coordinate>(5); p->push(Coordinate(1,2)); p->push(Coordinate(3,4)); p->stackTraverse(); Coordinate tmp = 0; p->pop(tmp); cout << endl << "tmp is "; tmp.printCoordinate(); p->clearStack(); cout << "Length: " << p->stackLength() << endl; if (p->stackEmpty()) { cout << "empty" << endl; } if (p->stackFull()) { cout << "full" << endl; } delete p; p = nullptr; return 0; }
实际应用一:进制转换